sclass ConceptFieldIndexCI implements IConceptIndex, IFieldIndex, IConceptCounter { Class cc; S field; new HashMap objectToValue; MultiMap valueToObject = ciMultiMap(); *() {} *(Class cc, S field) { this(db_mainConcepts(), cc, field); } *(Concepts concepts, Class *cc, S *field) { concepts.addConceptIndex(this); for (A c : list(concepts, cc)) updateImpl(c); concepts.addCIFieldIndex(cc, field, this); } public void update(Concept c) { if (!isInstance(cc, c)) ret; updateImpl(c); } synchronized void updateImpl(Concept c) { S newValue = cast cget(c, field); S oldValue = objectToValue.get(c); if (newValue == null || newValue != oldValue) { valueToObject.remove(oldValue, (A) c); valueToObject.put(newValue, (A) c); objectToValue.put((A) c, newValue); } } public synchronized void remove(Concept c) { if (!isInstance(cc, c)) ret; S value = cast cget(c, field); objectToValue.remove(c); valueToObject.remove(value, (A) c); } synchronized A get(S value) { ret valueToObject.getFirst(value); } public synchronized L getAll(S value) { ret valueToObject.get(value); } public Class conceptClass() { ret cc; } public int countConcepts() { ret l(objectToValue); } // Note: NOT SORTED public Collection allConcepts() { ret (Collection) keys(objectToValue); } public synchronized LS allValues() { ret cloneKeys_noSync(valueToObject.data); } public synchronized MultiSet allValues_multiSet() { ret multiMapToMultiSet(valueToObject); } // SORTED IterableIterator objectIterator() { ret navigableMultiMapValuesIterator(valueToObject); } }