How the Comparator Organizes Data

The basic mechanism for storing data in the Comparator is a blackboard. The Comparator blackboard is a globally visible, shared-memory data repository. The blackboard is organized into namespaces that are logical divisions of the data. Namespaces can contain other namespaces nested to any depth. Data is located in a namespace, and cannot contain namespaces or other pieces of data. Namespaces can be thought of as a tree, with the blackboard itself as the root and data at the leaves. Data and namespaces have an identifier that is unique within its namespace.

Applications can read data that someone has written to the blackboard, write their own data to the blackboard, or erase data from the blackboard. Typically, applications should not erase data unless they wrote it, and should not modify data without some agreement from the data's creator. Access to the blackboard is atomic, and applications can define conventions for synchronizing compound operations. Common synchronization conventions are to provide an access barrier, or to require all accesses be made from a single thread. Unlike some other blackboard systems, applications do not block waiting to read data from the Comparator. Instead, after modifying the blackboard, applications send out a notification message announcing their changes. Blackboard users can subscribe to these messages and wait for notice that data they are interested in has changed. To avoid waking other applications an excessive number of times, applications are encouraged to update data in blocks, and defer sending out notification messages until the block is complete. However, applications must send out a notification each time they end a synchronized access to data, since other applications might then attempt to access the blackboard.

Using

There are two ways to access data in the Comparator: directly through the Compare class and using the blackboard wrapper class Blackboard. The blackboard wrapper provides easier access to the most commonly used data access methods, and hides all of the other methods of the Comparator backend. The one type of operation not supported by the blackboard wrapper is atomically replacing one data value or namespace with another. However, this operation is rare in the Comparator system. Typically, an application will change a data value by operating on the object it points to, or change a namespace by modifying its contents.

Blackboard Methods

An application interested in receiving notifications from the blackboard must be registered using one of the addListener methods. Before the application terminates, it should be unregistered using the corresponding removeListener method.

To read from the blackboard:

  • Use the getData method to get the object associated with a data item.
  • Use the getNamespace method to access a namespace. The namespace will appear as another blackboard.
  • Use the scan method to atomically read all of the data contained in the namespace.

To write to the blackboard:

  • Use the addData method to create a data item.
  • Use the addNamespace method to create a namespace.

To erase from the blackboard:

  • Use the remove method. There is no difference between removing a data item or namespace.

Once a data item or namespace is created, it is typical to modify the object pointed to by the data item or modify the contents of the namespace rather than rewriting. To notify other blackboard users about changes:

  • Use the notify method after changing a data item or namespace. The name of the resource is picked by the application that created it.

Compare Methods

It is also possible to access the blackboard directly through the Comparator backend. The Comparator backend only provides easy access to data items in the top-level namespace and data items in namespaces in the top-level namespace. The Blackboard class makes using deeply nested namespaces easier and has less clutter than the Comparator backend. Changes from using the Blackboard class:

  • Instead of addListener and removeListener, use addPropertyChangeListener and removePropertyChangeListener.
  • Instead of getData and getNamespace, use getResource and getResourceMap. Namespaces will be returned as a Map. The getResourceMap method automatically creates a namespace with that name if one didn't already exist.
  • Instead of scan, use scanResources, scanResourceMap, or scanResourceCatalog.
  • Instead of addData or addNamspace, use addResource. Namespaces are created by pointing the resource at a Map.
  • Instead of remove, use removeResource.
  • Instead of notify, use firePropertyChange.

The following features are not possible in the Blackboard class:

  • The firePropertyChange method optionally allows the old and new values to be included in the notification message.
  • Use the getPropertyChangeListeners method to find all of the applications listening for notifications.
  • Use the replaceResource method to atomically replace a data item or namespace.
  • Use the updateResourceMap method to atomically replace a data item or namespace contained in another namespace.
  • Use the getResourceNames method to get the names of all current resources.

Existing Uses

Two data items and a namespace are defined by the Comparator in the top-level namespace. Most applications will never access these resources directly. Instead, these resources are accessed through methods in the Compare class. Notifications are not guaranteed when these resources are updated.

Three namespaces are defined by core Comparator classes in the top-level namespace.