use of io.atomix.core.tree.DocumentPath in project atomix by atomix.
the class DocumentTreeProxyBuilder method buildAsync.
@Override
@SuppressWarnings("unchecked")
public CompletableFuture<DocumentTree<V>> buildAsync() {
PrimitiveProtocol protocol = protocol();
PartitionGroup<?> partitions = managementService.getPartitionService().getPartitionGroup(protocol);
Map<PartitionId, CompletableFuture<AsyncDocumentTree<V>>> trees = Maps.newConcurrentMap();
for (Partition partition : partitions.getPartitions()) {
trees.put(partition.id(), partition.getPrimitiveClient().newProxy(name(), primitiveType(), protocol).connect().thenApply(proxy -> {
DocumentTreeProxy rawTree = new DocumentTreeProxy(proxy);
return new TranscodingAsyncDocumentTree<>(rawTree, serializer()::encode, serializer()::decode);
}));
}
Partitioner<DocumentPath> partitioner = key -> {
int bucket = (key == null) ? 0 : Math.abs(Hashing.murmur3_32().hashUnencodedChars(key.pathElements().size() == 1 ? key.pathElements().get(0) : key.pathElements().get(1)).asInt()) % NUM_BUCKETS;
return partitions.getPartitionIds().get(Hashing.consistentHash(bucket, partitions.getPartitionIds().size()));
};
return Futures.allOf(Lists.newArrayList(trees.values())).thenApply(t -> {
AsyncDocumentTree<V> tree = new PartitionedAsyncDocumentTree<>(name(), Maps.transformValues(trees, v -> v.getNow(null)), partitioner);
if (relaxedReadConsistency()) {
tree = new CachingAsyncDocumentTree<>(tree);
}
return tree.sync();
});
}
use of io.atomix.core.tree.DocumentPath in project atomix by atomix.
the class DocumentTreeService method update.
protected DocumentTreeResult<Versioned<byte[]>> update(Commit<? extends Update> commit) {
DocumentTreeResult<Versioned<byte[]>> result = null;
DocumentPath path = commit.value().path();
// If the path is locked by a transaction, return a WRITE_LOCK error.
if (isLocked(path)) {
return DocumentTreeResult.writeLock();
}
Versioned<byte[]> currentValue = docTree.get(path);
try {
Match<Long> versionMatch = commit.value().versionMatch();
Match<byte[]> valueMatch = commit.value().valueMatch();
if (versionMatch.matches(currentValue == null ? null : currentValue.version()) && valueMatch.matches(currentValue == null ? null : currentValue.value())) {
if (commit.value().value() == null) {
Versioned<byte[]> oldValue = docTree.removeNode(path);
result = new DocumentTreeResult<>(Status.OK, oldValue);
if (oldValue != null) {
notifyListeners(new DocumentTreeEvent<>(path, Type.DELETED, Optional.empty(), Optional.of(oldValue)));
}
} else {
Versioned<byte[]> oldValue = docTree.set(path, commit.value().value().orElse(null));
Versioned<byte[]> newValue = docTree.get(path);
result = new DocumentTreeResult<>(Status.OK, newValue);
if (oldValue == null) {
notifyListeners(new DocumentTreeEvent<>(path, Type.CREATED, Optional.of(newValue), Optional.empty()));
} else {
notifyListeners(new DocumentTreeEvent<>(path, Type.UPDATED, Optional.of(newValue), Optional.of(oldValue)));
}
}
} else {
result = new DocumentTreeResult<>(commit.value().value() == null ? Status.INVALID_PATH : Status.NOOP, currentValue);
}
} catch (IllegalDocumentModificationException e) {
result = DocumentTreeResult.illegalModification();
} catch (NoSuchDocumentPathException e) {
result = DocumentTreeResult.invalidPath();
} catch (Exception e) {
getLogger().error("Failed to apply {} to state machine", commit.value(), e);
throw Throwables.propagate(e);
}
return result;
}
use of io.atomix.core.tree.DocumentPath in project atomix by atomix.
the class DefaultDocumentTree method create.
@Override
public boolean create(DocumentPath path, V value) {
checkRootModification(path);
DocumentTreeNode<V> node = getNode(path);
if (node != null) {
return false;
}
DocumentPath parentPath = path.parent();
DefaultDocumentTreeNode<V> parentNode = getNode(parentPath);
if (parentNode == null) {
throw new IllegalDocumentModificationException();
}
parentNode.addChild(simpleName(path), value, versionSupplier.get());
return true;
}
use of io.atomix.core.tree.DocumentPath in project atomix by atomix.
the class DefaultDocumentTree method createRecursive.
@Override
public boolean createRecursive(DocumentPath path, V value) {
checkRootModification(path);
DocumentTreeNode<V> node = getNode(path);
if (node != null) {
return false;
}
DocumentPath parentPath = path.parent();
if (getNode(parentPath) == null) {
createRecursive(parentPath, null);
}
DefaultDocumentTreeNode<V> parentNode = getNode(parentPath);
if (parentNode == null) {
throw new IllegalDocumentModificationException();
}
parentNode.addChild(simpleName(path), value, versionSupplier.get());
return true;
}
use of io.atomix.core.tree.DocumentPath in project atomix by atomix.
the class DocumentTreeService method clear.
protected void clear(Commit<Void> commit) {
Queue<DocumentPath> toClearQueue = Queues.newArrayDeque();
Map<String, Versioned<byte[]>> topLevelChildren = docTree.getChildren(DocumentPath.from("root"));
toClearQueue.addAll(topLevelChildren.keySet().stream().map(name -> new DocumentPath(name, DocumentPath.from("root"))).collect(Collectors.toList()));
while (!toClearQueue.isEmpty()) {
DocumentPath path = toClearQueue.remove();
Map<String, Versioned<byte[]>> children = docTree.getChildren(path);
if (children.size() == 0) {
docTree.removeNode(path);
} else {
children.keySet().forEach(name -> toClearQueue.add(new DocumentPath(name, path)));
toClearQueue.add(path);
}
}
}
Aggregations