Accès aux données avec des index (API Index)

Utilisez l'indexation pour améliorer l'accès aux données.

Pourquoi et quand exécuter cette tâche

La classe HashIndex est l'implémentation de plug-in d'indexation intégré qui peut prendre en charge les deux interfaces d'indexation d'application intégrée MapIndex et MapRangeIndex. Vous pouvez également créer vos propres index. Vous pouvez ajouter HashIndex sous la forme d'un index statique ou dynamique dans la mappe de sauvegarde, obtenir soit un objet proxy d'index MapIndex ou MapRangeIndex et utiliser l'objet proxy d'index pour rechercher des objets mis en cache.

Si vous souhaitez exécuter une itération dans les clés d'une mappe locale, vous pouvez utiliser l'index par défaut. Cet index ne requiert pas de configuration, mais elle doit être utilisée sur le fragment en utilisant un agent ou une instance ObjectGrid extraits de la méthode ShardEvents.shardActivated(ObjectGrid shard).

Remarque : Dans un environnement réparti, si l'objet d'index est obtenu à partir d'un ObjectGrid client, l'index possède un objet de type client et toutes les opérations d'index sont exécutées dans un ObjectGrid de serveur. Si la mappe est partitionnée, les opérations d'indexation sont exécutées dans chaque partition à distance. Les résultats de chaque partition sont fusionnés avant de renvoyer les résultats à l'application. Les performances sont déterminées par le nombre de partitions et la taille des résultats renvoyés par chaque partition. Les performances peuvent être faibles si les deux facteurs sont élevés.

Procédure

  1. Si vous souhaitez utiliser des index autres que l'index local par défaut, ajoutez des plug-in d'index à la mappe de sauvegarde.
    • Configuration XML :
      <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>

      Dans cet exemple de configuration XML, la classe intégrée HashIndex est utilisée comme plug-in d'indexation. La classe HashIndex prend en charge les propriétés que les utilisateurs peuvent configurer, telles que Name, RangeIndex et AttributeName dans l'exemple précédent.

      • La propriété Name a la valeur CODE, une chaîne qui identifie ce plug-in d'index. La valeur de la propriété Name doit être unique dans l'étendue de la mappe de sauvegarde et peut servir à extraire l'objet d'index de l'instance ObjectMap pour la mappe de sauvegarde.
      • La propriété RangeIndex a la valeur true, ce qui signifie que l'application peut transtyper l'objet d'index extrait vers l'interface MapRangeIndex. Si la propriété RangeIndex a la valeur false, l'application peut transtyper uniquement l'objet d'index extrait vers l'interface MapIndex. Une interface MapRangeIndex prend en charge des fonctions de recherche de données à l'aide des fonctions de plage (range) telles que greater than, less than ou les deux, alors qu'un index MapIndex prend uniquement en charge les fonctions d'égalité (equals). Si l'index repose sur la requête, la propriété RangeIndex doit avoir la valeur true dans les index à un seul attribut. Dans le cas d'un index de relations ou d'un index composite, la propriété RangeIndex doit être configurée comme false.
      • La propriété AttributeName a la valeur employeeCode, ce qui implique que l'attribut employeeCode de l'objet en cache est utilisé pour créer un index à un seul attribut. Si une application doit rechercher des objets mis en cache avec plusieurs attributs, la propriété AttributeName peut être affectée d'une liste d'attributs séparés par une virgule pour produire un index composite.
    • Configuration à l'aide d'un programme :

      L'interface BackingMap comporte deux méthodes que vous pouvez utiliser pour ajouter des plug-in d'index statique : addMapIndexplugin et setMapIndexplugins. Pour plus d'informations, consultez API BackingMap. L'exemple suivant crée la même configuration que l'exemple de configuration XML :

      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");
      
          // utilisez la classe pré-intégrée HashIndex comme classe de plug-in d'indexation.
          HashIndex mapIndexplugin = new HashIndex();
          mapIndexplugin.setName("CODE");
          mapIndexplugin.setAttributeName("EmployeeCode");
          mapIndexplugin.setRangeIndex(true);
          personBackingMap.addMapIndexplugin(mapIndexplugin);
  2. Accédez aux clés de mappe et aux valeurs avec des index.
    • Index local :
      Pour effectuer une itération dans les clés d'une mappe locale, vous pouvez utiliser l'index par défaut. Cet index fonctionne uniquement avec le fragment, en utilisant un agent ou l'instance ObjectGrid extraits de la méthode ShardEvents.shardActivated(ObjectGrid shard). Reportez-vous à l'exemple suivant :
      MapIndex keyIndex = (MapIndex)
      objMap.getIndex(MapIndexPlugin.SYSTEM_KEY_INDEX_NAME);
      Iterator keyIterator = keyIndex.findAll();
    • Index statiques :

      Après l'ajout d'un plug-in d'index statique à une configuration de mappe de sauvegarde et l'initialisation de l'instance ObjectGrid contenante, les applications peuvent extraire l'objet d'index par nom à partir de l'instance ObjectMap pour la mappe de sauvegarde. Distribuez l'objet d'index vers l'interface d'index de l'application. Les opérations prises en charge par l'interface d'index de l'application peuvent désormais avoir lieu.

      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);
      }
      // Fermer la session (facultatif dans les versions 7.1.1 et ultérieures) pour améliorer les performances
      session.close();
    • Index dynamiques :

      Vous pouvez créer et supprimer à tout moment des index dynamiques d'une instance BackingMap. Un index dynamique diffère d'un index statique en ce qu'il peut être créé même après l'initialisation de l'instance ObjectGrid contenante. Contrairement à l'indexation statique, l'indexation dynamique est un processus asynchrone et doit être à l'état ready avant d'être utilisée. Cette méthode utilise la même approche pour extraire et utiliser les index dynamiques que pour les index statiques. Vous pouvez supprimer un index dynamique s'il n'est plus utile. L'interface BackingMap comprend deux méthodes pour créer et supprimer des index dynamiques.

      Voir la documentation de l'API BackingMap pour plus d'informations sur les méthodes createDynamicIndex et removeDynamicIndex.

      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();
      
              // créez l'index après l'initialisation de l'ObjectGrid sans DynamicIndexCallback.
              bm.createDynamicIndex("CODE", true, "employeeCode", null);
      
              try {
                  // Si DynamicIndexCallback n'est pas utilisé, attendre que l'index soit prêt.
                  // Le délai d'attente dépend de la taille actuelle de la mappe
                  Thread.sleep(3000);
              } catch (Throwable t) {
                  // ...
              }
      
              // Lorsque l'index est prêt, les applications peuvent tenter d'obtenir l'instance d'interface
              // de l'index d'application.
              // Les applications doivent trouver un moyen de vérifier que l'index est prêt à être utilisé,
              // faute de quoi elles utilisent l'interface DynamicIndexCallback.
              // L'exemple ci-dessous illustre comment attendre que l'index soit prêt
              // Prenez en compte la taille de la mappe dans le délai d'attente total.
      
              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) {
                      // implique que l'index n'est pas prêt, ...
                      System.out.println("Index pas prêt. continuez de patienter.");
                      try {
                          Thread.sleep(3000);
                      } catch (Throwable tt) {
                          // ...
                      }
                  } catch (Throwable t) {
                      // exception inattendue
                      t.printStackTrace();
                  }
              }
      
              if (!ready) {
                  System.out.println("Index pas prêt.  Remédiez à cette situation.");
              }
      
              // Utilisez l'index pour exécuter des requêtes
              // Reportez-vous à l'interface MapIndex ou MapRangeIndex pour les opérations prises en charge.
              // L'attribut d'objet sur lequel repose l'index est EmployeeCode.
              // Supposons que l'attribut EmployeeCode est de type entier : le
              // paramètre transmis aux opérations d'index présente ce type de données.
      
              Iterator iter = codeIndex.findLessEqual(new Integer(15));
      
              // supprimez l'index dynamique lorsqu'il n'est plus nécessaire
      
              bm.removeDynamicIndex("CODE");
      	// Fermer la session (facultatif dans les versions 7.1.1 et ultérieures) pour améliorer les performances
      	session.close();

Que faire ensuite

Vous pouvez utiliser l'interface DynamicIndexCallback pour obtenir des notifications des événements d'indexation. Pour plus d'informations, voir Interface DynamicIndexCallback.