MultipleFieldsTracker
This object tracks all the possible values of a subset of the columns of a store. It can be seen as a SELECT DISTINCT field1, field2, field3 FROM store
query.
It uses a continuous list view query to track the changes in real time.
The MultipleFieldsTracker is an extremely useful tool for creating a multi-level analysis hierarchy that needs to rely on the possible values of store fields.
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()
Tells if 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, fields);
}
@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 isAllMembersEnabled ?
Iterators.transform(allValues, this::addAllmenbers) :
allValues;
}
}