Indexes

The GCM language can be used to define both local and global indexes. Global indexes serve as entry points for the graph, whereas local indexes can be thought of indexed relationships.

Global indexes

Global indexes can be defined using the GCM language in form of a top-level declaration, as can be seen in the following example:

index Buildings : Building using name

This defines a global index Buildings for the type Building. The attribute name is used as only property for the index.

Based on this definition, the GCM generator generates methods to index, unindex and find nodes of type Building. The following code is generated by the generator.

public class Buildings {
  public static final Meta META = new Meta("Buildings",greycat.Type.INDEX,603612191);

  public static final void findAll(Graph graph, long world, long time,
      Callback<Building[]> callback) {
    graph.index(world, time, META.name, new Callback<NodeIndex>() {
      @Override
      public void on(NodeIndex idx) {
        if(idx != null) {
          idx.findFrom(new Callback<Node[]>() {
            @Override
            public void on(Node[] result) {
              Building[] typedResult = new Building[result.length];
              System.arraycopy(result, 0, typedResult, 0, result.length);
              idx.free();
              callback.on(typedResult);
            }
          });
        } else {
          callback.on(new Building[0]);
        }
      }
    });
  }

  public static final void find(Graph graph, long world, long time, String name,
      Callback<Building[]> callback) {
    graph.index(world, time, META.name, new Callback<NodeIndex>() {
      @Override
      public void on(NodeIndex idx) {
        if(idx != null) {
          idx.findFrom(new Callback<Node[]>() {
            @Override
            public void on(Node[] result) {
              Building[] typedResult = new Building[result.length];
              System.arraycopy(result, 0, typedResult, 0, result.length);
              idx.free();
              callback.on(typedResult);
            }
          },name);
        } else {
          callback.on(new Building[0]);
        }
      }
    });
  }

  public static final void update(Building toIndex, Callback<Boolean> callback) {
    toIndex.graph().index(toIndex.world(), toIndex.time(), META.name, new Callback<NodeIndex>() {
      @Override
      public void on(NodeIndex idx) {
        if(idx != null) {
          idx.update(toIndex);
          idx.free();
          if(callback != null) {
            callback.on(true);
          }
        } else {
          System.err.println("undeclared index Buildings");
          if(callback != null) {
            callback.on(false);
          }
        }
      }
    });
  }

  public static final void remove(Building toUnIndex, Callback<Boolean> callback) {
    toUnIndex.graph().index(toUnIndex.world(), toUnIndex.time(), META.name, new Callback<NodeIndex>() {
      @Override
      public void on(NodeIndex idx) {
        if(idx != null) {
          idx.unindex(toUnIndex);
          idx.free();
          if(callback != null) {
            callback.on(true);
          }
        } else {
          System.err.println("undeclared index Buildings");
          if(callback != null) {
            callback.on(false);
          }
        }
      }
    });
  }
}

Local indexes

Local indexes can be defined like in the following example:

class Building {
    index rooms : Room using name
}

Similar to global indexes, this defines an index rooms of node type Room using the attribute name as only property for the index. The GCM generator generates the following code:

public class Building {
  public static final Meta ROOMS = new Meta("rooms", greycat.Type.INDEX, 1283212327);

  public final Building indexRooms(Room value) {
    Index index = (Index) this.getAt(ROOMS.hash);
    index.update(value);
    return this;
  }

  public final Building unindexRooms(Room value) {
    Index index = (Index) this.getAt(ROOMS.hash);
    index.unindex(value);
    return this;
  }

  public final void findLocalRooms(String name, Callback<Room[]> callback) {
    Index index = (Index) this.getAt(ROOMS.hash);
    if(index != null) {
      index.find(new Callback<Node[]>() {
        @Override
        public void on(Node[] result) {
          Room[] typedResult = new Room[result.length];
          System.arraycopy(result, 0, typedResult, 0, result.length);
          callback.on(typedResult);
        }
      }, this.world(), this.time() ,name);
    } else {
      callback.on(new Room[0]);
    }
  }

  public final void findAllRooms(Callback<Room[]> callback) {
    Index index = (Index) this.getAt(ROOMS.hash);
    if(index != null) {
      index.find(new Callback<Node[]>() {
        @Override
        public void on(Node[] result) {
          Room[] typedResult = new Room[result.length];
          System.arraycopy(result, 0, typedResult, 0, result.length);
          callback.on(typedResult);
        }
      }, this.world(), this.time());
    } else {
      callback.on(new Room[0]);
    }
  }

    @Override
    public void init() {
      Index roomsIndex = (Index) this.getOrCreateAt(ROOMS.hash,greycat.Type.INDEX);
      roomsIndex.declareAttributes(null, Room.NAME.name);
    }
}

Indexes Properties

Both Indexes are used to provide faster and more efficient access to the data. However, they are not guaranting the unicity of the keys used as index, only the unicity of the key value pair, i.e., nodes can not be indexed twice, is enforced.

Thus in the case of our running example:

index Buildings : Building using name

Several different buildings sharing their name could be indexed.

results matching ""

    No results matching ""