Using indexing as an alternative to key access for data can be more efficient.
The HashIndex class is the index plug-in implementation that can support both of the built-in application index interfaces: MapIndex and MapRangeIndex. You can also create your own indexes.
If you want to write your own index plug-in, see Writing an index plug-in.
For information regarding indexing, see Indexing and Composite HashIndex.
You can use two approaches to add static index plug-ins into the BackingMap configuration: XML configuration and programmatic configuration. The following example illustrates the XML configuration approach.
Adding static index plug-ins: XML configuration approach
<backingMapPluginCollection id="person"> <bean id="MapIndexplugin" className="com.ibm.websphere.objectgrid.plugins.index.HashIndex"> <property name="Name" type="java.lang.String" value="CODE" description="index name" /> <property name="RangeIndex" type="boolean" value="true" description="true for MapRangeIndex" /> <property name="AttributeName" type="java.lang.String" value="employeeCode" description="attribute name" /> </bean> </backingMapPluginCollection>
In this XML configuration example, the built-in HashIndex class is used as the index plug-in. The HashIndex supports properties that users can configure, such as Name, RangeIndex, and AttributeName in the previous example.
See Configuring the HashIndex for more information.
The BackingMap interface has two methods that you can use to add static index plug-ins: addMapIndexplugin and setMapIndexplugins. For more information, see BackingMap API.
The following code example illustrates the programmatic configuration approach:
Adding static index plugins: programmatic configuration approach
import com.ibm.websphere.objectgrid.ObjectGridManagerFactory; import com.ibm.websphere.objectgrid.ObjectGridManager; import com.ibm.websphere.objectgrid.ObjectGrid; import com.ibm.websphere.objectgrid.BackingMap; ObjectGridManager ogManager = ObjectGridManagerFactory.getObjectGridManager(); ObjectGrid ivObjectGrid = ogManager.createObjectGrid( "grid" ); BackingMap personBackingMap = ivObjectGrid.getMap("person"); // use the builtin HashIndex class as the index plugin class. HashIndex mapIndexplugin = new HashIndex(); mapIndexplugin.setName("CODE"); mapIndexplugin.setAttributeName("EmployeeCode"); mapIndexplugin.setRangeIndex(true); personBackingMap.addMapIndexplugin(mapIndexplugin);
After a static index plug-in is added to a BackingMap configuration and the containing ObjectGrid instance is initialized, applications can retrieve the index object by name from the ObjectMap instance for the BackingMap. Cast the index object to the application index interface. Operations that the application index interface supports can now run.
The following code example illustrates how to retrieve and use static indexes.
Using static indexes example
Session session = ivObjectGrid.getSession(); ObjectMap map = session.getMap("person "); MapRangeIndex codeIndex = (MapRangeIndex) m.getIndex("CODE"); Iterator iter = codeIndex.findLessEqual(new Integer(15)); while (iter.hasNext()) { Object key = iter.next(); Object value = map.get(key); }
You can create and remove dynamic indexes from a BackingMap instance programmatically at any time. A dynamic index differs from a static index in that the dynamic index can be created even after the containing ObjectGrid instance is initialized. Unlike static indexing, the dynamic indexing is an asynchronous process and needs to be in ready state before you use it. This method uses the same approach for retrieving and using the dynamic indexes as static indexes. You can remove a dynamic index if it is no longer needed. The BackingMap interface has methods to create and remove dynamic indexes.
See the BackingMap API for more information about the createDynamicIndex and removeDynamicIndex methods.
Using dynamic indexes example
import com.ibm.websphere.objectgrid.ObjectGridManagerFactory; import com.ibm.websphere.objectgrid.ObjectGridManager; import com.ibm.websphere.objectgrid.ObjectGrid; import com.ibm.websphere.objectgrid.BackingMap; ObjectGridManager ogManager = ObjectGridManagerFactory.getObjectGridManager(); ObjectGrid og = ogManager.createObjectGrid("grid"); BackingMap bm = og.getMap("person"); og.initialize(); // create index after ObjectGrid initialization without DynamicIndexCallback. bm.createDynamicIndex("CODE", true, "employeeCode", null); try { // If not using DynamicIndexCallback, need to wait for the Index to be ready. // The waiting time depends on the current size of the map Thread.sleep(3000); } catch (Throwable t) { // ... } // When the index is ready, applications can try to get application index // interface instance. // Applications have to find a way to ensure that the index is ready to use, // if not using DynamicIndexCallback interface. // The following example demonstrates the way to wait for the index to be ready // Consider the size of the map in the total waiting time. Session session = og.getSession(); ObjectMap m = session.getMap("person"); MapRangeIndex codeIndex = null; int counter = 0; int maxCounter = 10; boolean ready = false; while (!ready && counter < maxCounter) { try { counter++; codeIndex = (MapRangeIndex) m.getIndex("CODE"); ready = true; } catch (IndexNotReadyException e) { // implies index is not ready, ... System.out.println("Index is not ready. continue to wait."); try { Thread.sleep(3000); } catch (Throwable tt) { // ... } } catch (Throwable t) { // unexpected exception t.printStackTrace(); } } if (!ready) { System.out.println("Index is not ready. Need to handle this situation."); } // Use the index to peform queries // Refer to the MapIndex or MapRangeIndex interface for supported operations. // The object attribute on which the index is created is the EmployeeCode. // Assume that the EmployeeCode attribute is Integer type: the // parameter that is passed into index operations has this data type. Iterator iter = codeIndex.findLessEqual(new Integer(15)); // remove the dynamic index when no longer needed bm.removeDynamicIndex("CODE");
The DynamicIndexCallback interface is designed for applications that want to get notifications at the indexing events of ready, error, or destroy. The DynamicIndexCallback is an optional parameter for the createDynamicIndex method of the BackingMap. With a registered DynamicIndexCallback instance, applications can run business logic upon receiving notification of an indexing event. For example, the ready event means that the index is ready for use. When a notification for this event is received, an application can try to retrieve and use the application index interface instance. See the DynamicIndexCallback API for more information.
The following code example illustrates the use of the DynamicIndexCallback interface:
Using DynamicIndexCallback interface
BackingMap personBackingMap = ivObjectGrid.getMap("person"); DynamicIndexCallback callback = new DynamicIndexCallbackImpl(); personBackingMap.createDynamicIndex("CODE", true, "employeeCode", callback); class DynamicIndexCallbackImpl implements DynamicIndexCallback { public DynamicIndexCallbackImpl() { } public void ready(String indexName) { System.out.println("DynamicIndexCallbackImpl.ready() -> indexName = " + indexName); // Simulate what an application would do when notified that the index is ready. // Normally, the application would wait until the ready state is reached and then proceed // with any index usage logic. if("CODE".equals(indexName)) { ObjectGridManager ogManager = ObjectGridManagerFactory.getObjectGridManager(); ObjectGrid og = ogManager.createObjectGrid( "grid" ); Session session = og.getSession(); ObjectMap map = session.getMap("person"); MapIndex codeIndex = (MapIndex) map.getIndex("CODE"); Iterator iter = codeIndex.findAll(codeValue); } } public void error(String indexName, Throwable t) { System.out.println("DynamicIndexCallbackImpl.error() -> indexName = " + indexName); t.printStackTrace(); } public void destroy(String indexName) { System.out.println("DynamicIndexCallbackImpl.destroy() -> indexName = " + indexName); } }