XodusIxMap extends XodusIxBase<T> implements IxMap<T> { private void reindex() { this.env.executeInExclusiveTransaction(txn -> { indexes.forEach((name, idx) -> env.truncateStore(idx.getName(), txn)); try (final Cursor ci = getMainDb().openCursor(txn)) { while (ci.getNext()) { ByteIterable pk = ci.getKey(); final T value = getValue(new Key(pk), Bytes.toBytes(ci.getValue())); indexFunctions.forEach((n, idxFun) -> { final Store idx = getIdx(n); idxFun.apply(value).forEach(ik -> idx.put(txn, ik.toByteIterable(), pk)); }); } } }); } XodusIxMap(final Xodus xodus,
                      final String name,
                      final Coder<T> coder,
                      final Map<String, Function<T, Set<Key>>> indexFunctions); Optional<T> get(Key primaryKey); Optional<T> get(Tx.Read tx, Key primaryKey); List<T> get(Tx.Read txn, Set<Key> primaryKeys); Optional<T> put(Tx.Write tx, Key primaryKey, T value); boolean modify(Tx.Write tx, Key primaryKey, Consumer<T> modifyValue); void delete(Tx.Write tx, Key primaryKey); Map<Key, T> getByIndex(String indexName, Tx.Read tx, Key indexKey); Map<Key, T> values(Tx.Read tx, Set<Key> pks); Set<Key> getPkByIndex(String indexName, Tx.Read tx, Key indexKey); Map<Key, T> getByIndexLessThan(String indexName, Tx.Read tx, Key indexKey); Map<Key, T> getByIndexNotLessThan(String indexName, Tx.Read tx, Key indexKey); Set<Key> getPkByIndexLessThan(String indexName, Tx.Read tx, Key indexKey); Set<Key> getPkByIndexGreaterThan(String indexName, Tx.Read tx, Key indexKey); Map<Key, T> getByIdxDescendingWhere(String indexName, Tx.Read tx, Predicate<T> p); Map<Key, T> getByIdxAscendingWhere(String indexName, Tx.Read tx, Predicate<T> p); void onDelete(BiConsumer<Tx.Write, Key> bf); @Override void clear(Tx.Write tx); @Override T toValue(byte[] bb); @Override XodusIxBase.Sizes sizeInfo(Tx.Read tx);  }
@Test public void testReindex() { ixMap = xodus.createIxMap("testReindex", ImmutableMap.of( "len", IxMapTest::stringLen, "lower", s -> Key.keys(Key.of(s.toLowerCase()))), CoderFactory.makeCoder(String.class)); Set<String> dbNames = new HashSet<>(rtx(tx -> xodus.getEnv().getAllStoreNames((Transaction) tx.txn()))); assertTrue(dbNames.containsAll(Sets.newHashSet("testReindex-idx-lower", "testReindex-idx-len", "testReindex-main"))); wtx0(tx -> ixMap.put(tx, Key.of(1L), "aa")); wtx0(tx -> ixMap.put(tx, Key.of(2L), "aBa")); assertEquals(ImmutableMap.of(Key.of(1L), "aa"), xodus.readTx(tx -> ixMap.getByIndex("len", tx, intKey(2)))); assertEquals(ImmutableMap.of(Key.of(2L), "aBa"), xodus.readTx(tx -> ixMap.getByIndex("len", tx, intKey(3)))); assertEquals(ImmutableMap.of(Key.of(2L), "aBa"), xodus.readTx(tx -> ixMap.getByIndex("lower", tx, Key.of("aba")))); ixMap = xodus.createIxMap("testReindex", ImmutableMap.of( "lenPlus1", s -> Key.keys(intKey(s.length() + 1)), "lower", s -> Key.keys(Key.of(s.toLowerCase()))), CoderFactory.makeCoder(String.class)); Set<String> dbNames1 = new HashSet<>(rtx(tx -> xodus.getEnv().getAllStoreNames((Transaction) tx.txn()))); assertTrue(dbNames1.containsAll(Sets.newHashSet("testReindex-idx-lower", "testReindex-idx-lenPlus1", "testReindex-main"))); assertFalse(dbNames1.contains("testReindex-idx-len")); assertEquals(Optional.of("aa"), xodus.readTx(tx -> ixMap.get(tx, Key.of(1L)))); assertEquals(Optional.of("aBa"), xodus.readTx(tx -> ixMap.get(tx, Key.of(2L)))); assertEquals(ImmutableMap.of(), xodus.readTx(tx -> ixMap.getByIndex("len", tx, intKey(2)))); assertEquals(ImmutableMap.of(Key.of(1L), "aa"), xodus.readTx(tx -> ixMap.getByIndex("lenPlus1", tx, intKey(3)))); assertEquals(ImmutableMap.of(Key.of(2L), "aBa"), xodus.readTx(tx -> ixMap.getByIndex("lenPlus1", tx, intKey(4)))); assertEquals(ImmutableMap.of(Key.of(2L), "aBa"), xodus.readTx(tx -> ixMap.getByIndex("lower", tx, Key.of("aba")))); }