AgE 2.4 : ZapytaniaImplOpisMechanizmu

Opis mechanizmu query

Mechanizm zapytań jest formą komunikacji między agentami. Wykonując query na dowolnym agregacie agent może uzyskać od niego zestaw właściwości jego agentów spełniających dowolne kryteria.

Podstawowym interfejsem mechanizmu jest IQuery. Cykl operacji na IQuery przedstawia się następująco:

  • init(IAgent) - na tym etapie IQuery tworzy i inicjalizuje (w razie potrzeby korzystając ze specyficznych pól wywołującego je agenta) obiekt typu IQueryResult który następnie zwraca.
  • shouldStop(IAgent, IQueryResult) - na tym etapie IQuery sprawdza czy powinno zaprzestać aktualizacji podanego rezultatu (w razie potrzeby korzystając ze specyficznych pól agenta) gdyż jest on aktualny.
  • update(IPropertiesSet, IQueryResult) - na tym etapie IQuery dokonuje pełnej aktualizacji podanego rezultatu (w razie potrzeby korzystając ze specyficznych propertiesów konkretnego agenta dla którego dokonywana jest aktualizacja), etap właściwego wyznaczania wartości query, z reguły najbardziej złożony obliczeniowo, najczęściej etap ten składa się z wywołań update(IPropertiesSet, IQueryResult) dla zbiorów propertiesów wszystkich agentów agregata.
  • finish(IAgent, IQueryResult) - na tym etapie w razie potrzeby IQuery dokonuje dowolnych operacji zamykających koniecznych po wykonaniu query na rezultacie lub wywołującym agencie.

Przygotowano prostą implementację RecordingQuery (na diagramie: AggregatingQuery), dokonującą zbierania (agregowania) zbiorów propertiesów bez ich dogłębniejszej analizy. Zdefiniowane w niej query jest zbiorem constraintów (IConstraintEntry) i funkcji (IQueryFunction). IConstraintEntry to połączenie nazwy property na które narzucony jest constraint oraz samego constraintu. Constrainty to klasy sprawdzające czy uzyskany z property obiekt spełnia kryteria wyszukiwania. Zaimplementowano cztery podstawowe typy constraintów:

  • ValueConstraint - dla dowolnych obiektów - sprawdza równość tych obiektów z założonymi, w przypadku liczb (podklas java.lang.Number) sprawdzana jest wartość liczbowa a nie sama klasa obiektu, tj. na przykład Short o wartości 3 jest równy Longowi o wartości 3.
  • RangeConstraint - dla wartości liczbowych - sprawdza czy uzyskane wartości mieszczą się w założonym zasięgu, w granicach zasięgu sprawdzana jest wartość liczbowa a nie sama klasa obiektu (jak wyżej).
  • PatternConstraint - dla wartości znakowych - sprawdza czy uzyskany string jest zgodny z wzorcem
  • InvertedConstraint - dla dowolnego zdefiniowanego constrainta - constraint do niego odwrotny

Funkcje to zbiór przekształceń na rezultatach query, są ustawione w listę i wykonywane kolejno.

Klasa umożliwia dodawanie do query constraintów i funkcji za pomocą kodu, jest także ClassPropertyContainer, co oznacza że można ją zdefiniować za pomocą konfiguracji jAgE. Domyślna implementacja IConstraintEntry (ConstraintEntry), wszystkie zdefiniowane rodzaje constraintów a także abstrakcyjna klasa funkcji AbstractQueryFunction także są ClassPropertyContainerami, więc także mogą być definiowane za pomocą konfiguracji.

Klasa przechowuje także konfiguracyjną nazwę (czyli nazwę pod jakim znajduje się on w konfiguracji jAgE) rezultatu jaki jest tworzony na etapie inicjalizacji query.

Taka definicja pozwala na dowolne zdefiniowanie query. Z reguły jest to jednak uciążliwe, szczególnie w przypadku gdy plik konfiguracyjny bardzo puchnie od skomplikowanych constraintów. Ponadto takie podejście zazwyczaj jest nieefektywne.

W wielu przypadkach prościej dla użytkownika jest zaimplementować własne IQuery, które wykonuje pożądanych selekcji i przekształceń. Nic nie stoi na przeszkodzie aby użytkownik korzystał w tej implementacji z przygotowanych constraintów i funkcji, może jednak równie dobrze zastosować jakieś własne podejście, specyficzne dla poszukiwanego rozwiązania i przez to znacznie efektywniejsze w użyciu.

Obiekty na których można wykonywać query implementują interfejs IQueryable. Interfejs ten jest rozszerzany w dwie strony.

  • Z jednej strony rozszerza go interfejs IAgentEnvironment dodający możliwość wykonywania query na rodzicu oraz uzyskanie adresu agenta, implementowany przez każdego workplace'a. Jego kolejnym rozszerzeniem jest ISimpleAgentEnvironment implementowany przez każdego agregata, stąd query można wykonywać na każdym agregacie.
  • Z drugiej strony przygotowano klasę QueryableQueryResult (będącą IQueryResultem) reprezentującą wyspecjalizowany rezultat wykonanego query na którym można wykonać kolejne query.

Attachments:

query.png (image/png)
queryable.png (image/png)