IBM®
Skip to main content
    Country/region [select]      Terms of use
 
 
    
     Home      Products      Services & solutions      Support & downloads      My account     
 
developerworks > My developerWorks >  Dashboard > WebSphere eXtreme Scale V6.1 User Guide > ... > Indexing > Using indexing for non-key data access
developerWorks
Log In   View a printable version of the current page.
Overview Connect Spaces Forums Wikis
Using indexing for non-key data access
Added by cheng1, last edited by saif.patel@us.ibm.com on Jan 15, 2009  (view change)
Labels: 
(None)

Getting Started Examples Reference API documentation

See the WebSphere eXtreme Scale Wiki for links to eXtreme Scale Version 7.0 documentation.
If you log in with your developerWorks ID, you can leave comments and feedback for the development team.

The following steps explain how to use indexing:

  • Add either static or dynamic index plug-ins to the BackingMap.
  • Obtain application index proxy object by issuing the getIndex method of ObjectMap.
  • Cast the index proxy object to an appropriate application index interface, such as MapIndex, MapRangeIndex, or a customized index interface.
  • Use the methods that are defined in an application index interface to find cached objects.

The HashIndex class is the built-in index plug-in implementation that can support both of the built-in application index interfaces: MapIndex and MapRangeIndex. Applications can provide their own index plug-in implementation to support the programming of more complex indices.

If you are interested in writing your own index plugin, see Writing a MapIndexPlugin plug-in.
For information regarding indexing, see Indexing.

Adding static index plug-ins

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 plugins: 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>

The BackingMap interface has two methods that you can use to add static index plug-ins: the addMapIndexPlugin and the setMapIndexPlugins method. The following example presents the definition of these two methods.

addMapIndexPlugin and setMapIndexPlugins method of BackingMap
/**
     * Adds an <code>MapIndexPlugin</code> to this Map. This method assumes the index implementation was constructed
     * with the name of the attribute to index. The name of the index is specified when
     * the index is constructed.
     * <p>
     * Note, to avoid an <code>IllegalStateException</code>, this method must be called
     * prior to <code>ObjectGrid.initialize()</code> method.  Also, keep in mind that the
     * <code>ObjectGrid.getSession()</code> method implicitly calls the
     * <code>ObjectGrid.initialize()</code> method if it has yet to be called by the application.
     *
     * @param index The index implementation.
     *
     * @throws IndexAlreadyDefinedException if this index already exists.
     * @throws IllegalStateException if this method is called after the
     *         <code>ObjectGrid.initialize()</code> method is called.
     *
     * @see MapIndexPlugin
     * @see ObjectGrid#initialize()
     * @see ObjectGrid#getSession()
     */
    public void addMapIndexPlugin(MapIndexPlugin index)
        throws IndexAlreadyDefinedException;


    /**
     * Sets the list of <code>MapIndexPlugin</code> objects for this BackingMap.
     * If the BackingMap already has a <code>List</code> of <code>MapIndexPlugin</code> objects,
     * that list is replaced by the <code>List</code> passed as
     * an argument to the current invocation of this method.
     * <p>
     * Note, to avoid an <code>IllegalStateException</code>, this method must be called
     * prior to <code>ObjectGrid.initialize()</code> method.  Also, keep in mind that the
     * <code>ObjectGrid.getSession()</code> method implicitly calls the
     * <code>ObjectGrid.initialize()</code> method if it has yet to be called by the application.
     *
     * @param indexList  A non-null reference to a <code>List</code> of <code>MapIndexPlugin</code> objects.
     *
     * @throws IllegalArgumentException is thrown if indexList is null
     *         or the indexList contains either a <code>null</code> reference
     *         or an object that is not an instanceof <code>MapIndexPlugin</code>.
     *
     * @see MapIndexPlugin
     * @see ObjectGrid#initialize()
     * @see ObjectGrid#getSession()
     */
    public abstract void setMapIndexPlugins(List /* MapIndexPlugin */ indexList );

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);

Using static indices

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 map. Cast the index object to the application index interface. Index operations that are supported by the application index interface can now run.

The following code example illustrates how to retrieve and use static indices:

Using staic indices 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);
    }

Adding, removing, and using dynamic indices

You can create and remove dynamic indices 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 serving its purpose. This method uses the same approach for retrieving and using the dynamic indices as static indices. You can remove a dynamic index if it is no longer needed. The BackingMap interface has methods to create and remove dynamic indices. The following example presents the definition of these methods:

createDynamicIndex and removeDynamicIndex method of BackingMap
/**
     * Create a dynamic index on the BackingMap instance
     *
     * @param name
     *            The name of the index. The name cannot be null.
     * @param isRangeIndex
     *            Indicate whether to create a MapRangeIndex or a MapIndex index. If set to true, the index has a type
     *            of MapRangeIndex.
     * @param attributeName
     *            The name of the attribute index. The attributeName value cannot be null.
     * @param dynamicIndexCallback
     *            The callback that invokes on dynamic index events. The dynamicIndexCallback parameter is optional and
     *            can be null.
     *
     * @throws IndexAlreadyDefinedException
     *             if a MapIndexPlugin plug-in with the specified name already exists.
     *
     */
    public void createDynamicIndex(String name, boolean isRangeIndex, String attributeName, DynamicIndexCallback cb)
            throws IndexAlreadyDefinedException, UnsupportedOperationException;

    /**
     * Create a dynamic index on the BackingMap instance.
     *
     * @param index
     *            The index implementation. The index cannot be null.
     * @param dynamicIndexCallback
     *            The callback that invokes on dynamic index events. The dynamicIndexCallback parameter is optional and
     *            can be null.
     *
     * @throws IndexAlreadyDefinedException
     *             if a MapIndexPlugin plug-in with the specified name already exists.
     */
    public void createDynamicIndex(MapIndexPlugin index, DynamicIndexCallback dynamicIndexCallback)
            throws IndexAlreadyDefinedException, UnsupportedOperationException;

    /**
     * remove a dynamic index from the BackingMap instance
     *
     * @param name
     *            The name of the index. The name cannot be null.
     *
     * @throws IndexUndefinedException
     *             if a MapIndexPlugin plug-in with the specified name does not exist.
     *
     */
    public void removeDynamicIndex(String name) throws IndexUndefinedException;

The following code example illustrates the programmatic approach of creating, using, and removing a dynamic index:

Using dynamic indices 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");

DynamicIndexCallback interface

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. The following example shows the definition of the DynamicIndexCallback Interface:

DynamicIndexCallback interface
/**
 * This is the callback interface for dynamic indexing process.
 * To get notification at the event of ready, error,
 * or destroy, implement this callback interface and register with
 * the dynamic indexing process when creating a dynamic index.
 *
 */

import com.ibm.websphere.objectgrid.BackingMap;
import com.ibm.websphere.objectgrid.ObjectGrid;

/**
 * This interface provides a callback mechanism for dynamic indexing process. If applications wish to get notification
 * at the event a dynamic index is ready, in error, or destroyed, they can implement this callback interface and
 * register it with the dynamic indexing process when creating a dynamic index.
 *
 * @ibm-api
 * @since WAS XD 6.0.1
 *
 * @see BackingMap#createDynamicIndex(MapIndexPlugin, DynamicIndexCallback)
 * @see BackingMap#createDynamicIndex(String, boolean, String, DynamicIndexCallback)
 */
public interface DynamicIndexCallback {

    /**
     * Invoked when the dynamic index is ready.
     *
     * @param indexName
     *            the index name
     */
    public void ready(String indexName);

    /**
     * Invoked when the dynamic indexing process encounters an unexpected error.
     *
     * @param indexName
     *            the index name
     * @param t
     *            a Throwable object that caused the error situation in dynamic indexing processing.
     */
    public void error(String indexName, Throwable t);

    /**
     * Invoked when the dynamic index is removed or the BackingMap is destroyed.
     *
     * @param indexName
     *            the index name
     *
     * @see BackingMap#removeDynamicIndex(String)
     * @see ObjectGrid#destroy()
     */
    public void destroy(String indexName);
}

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);
        }
    }
Wiki Disclaimer and License
© Copyright IBM Corporation 2007,2009. All Rights Reserved.


 
    About IBM Privacy Contact