Skip to content

Indices

Jan Wiemer edited this page Mar 13, 2022 · 4 revisions

Indices

An important feature in many applications is to access data based on different access keys. Generally the objects in a store, just like the objects in a normal map, are stored based on one single key. Using this key the store / map provides very efficient access to the objects. If we want to access one or many objects with a certain property different to the key we would have to traverse all stored objects and compare the property with the search key (causing linear computation effort). To provide faster access a common concept is to use indices. An index provides fast access (based on an index map) for a defined index key.

Since version 2.0.12 JACIS supports unique and non-unique indices. An index can be defined at the store giving it a unique name and a function used to compute the index key for an object. In the simplest case the function can be a simple projection to a property of the stored object. However the function can also combine properties or do simple computations. When creating an index we have to decide if the index is unique (there is only at most one single object for each index key), or non unique:

  • unique indices are created with the method: createUniqueIndex

  • non unique indices are created with the method: createNonUniqueIndex

Both methods get the (unique) name of the index and a function computing the index key for an object as parameter. Later the indices can be accessed by name using the getUniqueIndex or getNonUniqueIndex methods.

The createUniqueIndex and getUniqueIndex return a JacisUniqueIndex class. This class provides a get and a getReadOnly method getting an index key as parameter and returning the unique object for the index key. The method getPrimaryKey can be used to get the primary key of the object for the index key. The primary key is the normal key of the store. Note that if a unique index is registered the attempt to update an object in a way that the unique index would be violated causes an exception.

The createNonUniqueIndex and getNonUniqueIndex return a JacisNonUniqueIndex class. This class provides a get and a getReadOnly method getting an index key as parameter and returning the set of all objects for the index key. The method getPrimaryKeys can be used to get the primary keys of the objects for the index key.

The following example shows the usage of a non unique index:

    JacisContainer container = new JacisContainer();
    JacisObjectTypeSpec<String, Account, Account> objectTypeSpec //
        = new JacisObjectTypeSpec<>(String.class, Account.class, new JacisCloningObjectAdapter<>());
    JacisStore<String, Account> store = container.createStore(objectTypeSpec).getStore();

    JacisNonUniqueIndex<Long, String, Account> balanceIdx = store.createNonUniqueIndex("BALANCE-IDX", acc -> acc.getBalance());

    container.withLocalTx(() -> {
      store.update("ACC1", new Account("Acc1").deposit(10l));
      store.update("ACC2", new Account("Acc2").deposit(10l));
      store.update("ACC3", new Account("Acc3").deposit(20l));
    });
    Collection<Account> accounts = balanceIdx.getReadOnly(10l);
    System.out.println("accounts with balance 10 after first TX:");
    accounts.forEach(acc -> System.out.println(" - " + acc.getName()));

    container.withLocalTx(() -> {
      store.update("ACC4", new Account("Acc1").deposit(10l));
      Collection<Account> accounts2 = balanceIdx.getReadOnly(10l);
      System.out.println("accounts with balance 10 in second TX:");
      accounts2.forEach(acc -> System.out.println(" - " + acc.getName()));
    });

Next Chapter: Tracked Views