UniqueFieldTracker

This object tracks all the possible values of a store column. It can be seen as a SELECT DISTINCT field FROM store query. It replaces direct access to the values of the inner store dictionary and uses a continuous list view query to track the changes in real time. The UniqueFieldTracker is an extremely useful tool for creating an analysis hierarchy that needs to rely on the possible values of a store field.

Functions

getValues(branch)

Returns an iterator on the different (unique) values of the latest epoch of the selected branch.

getValuesInTransaction()

Returns an iterator on the different (unique) values of the epoch under the current transaction.

haveNewValues(branch)

Tells if there have been changes since the last call, subsequent calls will return false.

haveNewValues()

Tells if there have been changes since the last call (committed or uncommitted). Subsequent calls will return false.

haveNewValuesInTransaction()

It tells changes are occurring within this transaction.

cleanUp()

Frees memory by removing discarded data.

isInTransaction()

Tells if there is a running transaction.

waitCompletion()

Waits for the initial load completion. It is mainly provided for tests.

Usage in an analysis hierarchy plugin

Here is how it can be used:

@QuartetExtendedPluginValue(intf = IMultiVersionHierarchy.class, key = MyHierarchy.PLUGIN_KEY)
public class MyHierarchy extends AAnalysisHierarchyV2 {

    protected final transient IFieldTracker<Object> storeTracker;

    @Override
    public void setDatabase(IDatabase database) {
        super.setDatabase(database);
        storeTracker = new UniqueFieldTracker<>(database, store, fieldPath);
    }

    @Override
    public boolean getNeedRebuild() {
        return storeTracker.haveNewValues();
    }

    @Override
    protected Iterator<Object[]> buildDiscriminatorPathsIterator(@NonNull IDatabaseVersion database) {
        storeTracker.cleanUp();
        // This function is called during a 2 phase commit so the incoming data may be still in transaction.
        Iterator<Object> allValues = storeTracker.isInTransaction() ?
                storeTracker.getValuesInTransaction() :
                storeTracker.getValues(database.getEpoch().getBranch());
        return Iterators.transform(allValues, isAllMembersEnabled ?
                member -> new Object[] { ALLMEMBER, member } :
                member -> new Object[] { member });
    }
}