@Override public Iterable<String> query(Filter filter, String indexName, NodeState indexMeta, Iterable<String> values) { return strategy.query(filter, indexName, indexMeta, values); }
@Override public long count(Filter filter, NodeState root, NodeState indexMeta, Set<String> values, int max) { return strategy.count(filter, root, indexMeta, values, max); }
private void update(Set<IndexStoreStrategy> refStores, NodeBuilder definition, String name, String key, Set<String> add, Set<String> rm) throws CommitFailedException { for (IndexStoreStrategy store : refStores) { Set<String> empty = of(); for (String p : rm) { Supplier<NodeBuilder> index = memoize(() -> definition.child(store.getIndexNodeName())); store.update(index, p, name, definition, of(key), empty); } for (String p : add) { // TODO do we still need to encode the values? Supplier<NodeBuilder> index = memoize(() -> definition.child(store.getIndexNodeName())); store.update(index, p, name, definition, empty, of(key)); } } }
/** * From a set of keys, get the first that has multiple entries, if any. * * @param keys the keys * @param indexMeta the index configuration * @return the first duplicate, or null if none was found */ private String getFirstDuplicate(Set<String> keys, NodeState indexMeta) { for (String key : keys) { long count = 0; for (IndexStoreStrategy s : getStrategies(true)) { count += s.count(root, indexMeta, singleton(key), 2); if (count > 1) { Iterator<String> it = s.query(null, null, indexMeta, singleton(key)).iterator(); if (it.hasNext()) { return key + ": " + it.next(); } return key; } } } return null; }
@Test public void nonRootStorage() throws Exception{ IndexStoreStrategy store = new ContentMirrorStoreStrategy(INDEX_CONTENT_NODE_NAME, "/content", false); NodeState root = EMPTY_NODE; NodeBuilder builder = root.builder(); Supplier<NodeBuilder> index = () -> builder; for (String path : asList("a", "a/c", "b")) { store.update(index, path, null, null, EMPTY, KEY); } FilterImpl filter = FilterImpl.newTestInstance(); filter.restrictPath("/content", Filter.PathRestriction.ALL_CHILDREN); NodeBuilder indexMeta = EMPTY_NODE.builder(); indexMeta.setChildNode(INDEX_CONTENT_NODE_NAME, builder.getNodeState()); Iterable<String> paths = store.query(filter, null, indexMeta.getNodeState(), KEY); assertThat(copyOf(paths), containsInAnyOrder("a", "a/c", "b")); FilterImpl filter2 = FilterImpl.newTestInstance(); filter2.restrictPath("/content/a", Filter.PathRestriction.ALL_CHILDREN); paths = store.query(filter2, null, indexMeta.getNodeState(), KEY); assertThat(copyOf(paths), containsInAnyOrder("a", "a/c")); store = new ContentMirrorStoreStrategy(INDEX_CONTENT_NODE_NAME, "/content", true); paths = store.query(filter, null, indexMeta.getNodeState(), KEY); assertThat(copyOf(paths), containsInAnyOrder("/content/a", "/content/a/c", "/content/b")); paths = store.query(filter2, null, indexMeta.getNodeState(), KEY); assertThat(copyOf(paths), containsInAnyOrder("/content/a", "/content/a/c")); }
@Test public void testUnique() throws CommitFailedException { IndexStoreStrategy store = new ContentMirrorStoreStrategy(); NodeState root = EMPTY_NODE; NodeBuilder indexMeta = root.builder(); Supplier<NodeBuilder> index = memoize(() -> indexMeta.child(INDEX_CONTENT_NODE_NAME)); store.update(index, "a", null, null, EMPTY, KEY); store.update(index, "b", null, null, EMPTY, KEY); Assert.assertTrue( "ContentMirrorStoreStrategy should guarantee uniqueness on insert", store.count(root, indexMeta.getNodeState(), Collections.singleton("key"), 2) > 1); }
@Override public void update(Supplier<NodeBuilder> index, String path, String indexName, NodeBuilder indexMeta, Set<String> beforeKeys, Set<String> afterKeys) throws CommitFailedException { if (filter.apply(path)) { if (readOnly) { throw new CommitFailedException( CommitFailedException.UNSUPPORTED, 0, "Unsupported commit to a read-only store!", new Throwable("Commit path: " + path)); } strategy.update(index, path, indexName, indexMeta, beforeKeys, afterKeys); } }
@Override public boolean exists(Supplier<NodeBuilder> index, String key) { return strategy.exists(index, key); }
@Override public String getIndexNodeName() { return strategy.getIndexNodeName(); }
/** * From a set of keys, get the first that has multiple entries, if any. * * @param keys the keys * @param indexMeta the index configuration * @return the first duplicate, or null if none was found */ private String getFirstDuplicate(Set<String> keys, NodeState indexMeta) { for (String key : keys) { long count = 0; for (IndexStoreStrategy s : getStrategies(true)) { count += s.count(root, indexMeta, singleton(key), 2); if (count > 1) { Iterator<String> it = s.query(null, null, indexMeta, singleton(key)).iterator(); if (it.hasNext()) { return key + ": " + it.next(); } return key; } } } return null; }
@Override public void update(Supplier<NodeBuilder> index, String path, String indexName, NodeBuilder indexMeta, Set<String> beforeKeys, Set<String> afterKeys) throws CommitFailedException { if (filter.apply(path)) { if (readOnly) { throw new CommitFailedException( CommitFailedException.UNSUPPORTED, 0, "Unsupported commit to a read-only store!", new Throwable("Commit path: " + path)); } strategy.update(index, path, indexName, indexMeta, beforeKeys, afterKeys); } }
@Override public boolean exists(Supplier<NodeBuilder> index, String key) { return strategy.exists(index, key); }
@Override public String getIndexNodeName() { return strategy.getIndexNodeName(); }
@Override public Iterable<String> query(Filter filter, String indexName, NodeState indexMeta, Iterable<String> values) { return strategy.query(filter, indexName, indexMeta, values); }
@Override public long count(NodeState root, NodeState indexMeta, Set<String> values, int max) { return strategy.count(root, indexMeta, values, max); }
private void update(Set<IndexStoreStrategy> refStores, NodeBuilder definition, String name, String key, Set<String> add, Set<String> rm) throws CommitFailedException { for (IndexStoreStrategy store : refStores) { Set<String> empty = of(); for (String p : rm) { Supplier<NodeBuilder> index = memoize(() -> definition.child(store.getIndexNodeName())); store.update(index, p, name, definition, of(key), empty); } for (String p : add) { // TODO do we still need to encode the values? Supplier<NodeBuilder> index = memoize(() -> definition.child(store.getIndexNodeName())); store.update(index, p, name, definition, empty, of(key)); } } }
/** * From a set of keys, get the first that has multiple entries, if any. * * @param keys the keys * @param indexMeta the index configuration * @return the first duplicate, or null if none was found */ private String getFirstDuplicate(Set<String> keys, NodeState indexMeta) { for (String key : keys) { long count = 0; for (IndexStoreStrategy s : getStrategies(true)) { count += s.count(root, indexMeta, singleton(key), 2); if (count > 1) { Iterator<String> it = s.query(null, null, indexMeta, singleton(key)).iterator(); if (it.hasNext()) { return key + ": " + it.next(); } return key; } } } return null; }
@Override public void update(Supplier<NodeBuilder> index, String path, String indexName, NodeBuilder indexMeta, Set<String> beforeKeys, Set<String> afterKeys) throws CommitFailedException { if (filter.apply(path)) { if (readOnly) { throw new CommitFailedException( CommitFailedException.UNSUPPORTED, 0, "Unsupported commit to a read-only store!", new Throwable("Commit path: " + path)); } strategy.update(index, path, indexName, indexMeta, beforeKeys, afterKeys); } }
@Override public boolean exists(Supplier<NodeBuilder> index, String key) { return strategy.exists(index, key); }
@Override public String getIndexNodeName() { return strategy.getIndexNodeName(); }