Search in sources :

Example 1 with DocumentPath

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();
    });
}
Also used : Preconditions.checkNotNull(com.google.common.base.Preconditions.checkNotNull) AsyncDocumentTree(io.atomix.core.tree.AsyncDocumentTree) Hashing(com.google.common.hash.Hashing) DocumentPath(io.atomix.core.tree.DocumentPath) CompletableFuture(java.util.concurrent.CompletableFuture) Maps(com.google.common.collect.Maps) PartitionGroup(io.atomix.primitive.partition.PartitionGroup) DocumentTree(io.atomix.core.tree.DocumentTree) PartitionId(io.atomix.primitive.partition.PartitionId) DocumentTreeBuilder(io.atomix.core.tree.DocumentTreeBuilder) Lists(com.google.common.collect.Lists) Partition(io.atomix.primitive.partition.Partition) PrimitiveManagementService(io.atomix.primitive.PrimitiveManagementService) PrimitiveProtocol(io.atomix.primitive.PrimitiveProtocol) Map(java.util.Map) Partitioner(io.atomix.primitive.partition.Partitioner) Futures(io.atomix.utils.concurrent.Futures) Partition(io.atomix.primitive.partition.Partition) PartitionId(io.atomix.primitive.partition.PartitionId) CompletableFuture(java.util.concurrent.CompletableFuture) DocumentPath(io.atomix.core.tree.DocumentPath) PrimitiveProtocol(io.atomix.primitive.PrimitiveProtocol)

Example 2 with DocumentPath

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;
}
Also used : Versioned(io.atomix.utils.time.Versioned) AtomicLong(java.util.concurrent.atomic.AtomicLong) DocumentPath(io.atomix.core.tree.DocumentPath) NoSuchDocumentPathException(io.atomix.core.tree.NoSuchDocumentPathException) IllegalDocumentModificationException(io.atomix.core.tree.IllegalDocumentModificationException) NoSuchDocumentPathException(io.atomix.core.tree.NoSuchDocumentPathException) IllegalDocumentModificationException(io.atomix.core.tree.IllegalDocumentModificationException)

Example 3 with DocumentPath

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;
}
Also used : DocumentPath(io.atomix.core.tree.DocumentPath) IllegalDocumentModificationException(io.atomix.core.tree.IllegalDocumentModificationException)

Example 4 with DocumentPath

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;
}
Also used : DocumentPath(io.atomix.core.tree.DocumentPath) IllegalDocumentModificationException(io.atomix.core.tree.IllegalDocumentModificationException)

Example 5 with DocumentPath

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);
        }
    }
}
Also used : Versioned(io.atomix.utils.time.Versioned) DocumentPath(io.atomix.core.tree.DocumentPath)

Aggregations

DocumentPath (io.atomix.core.tree.DocumentPath)5 IllegalDocumentModificationException (io.atomix.core.tree.IllegalDocumentModificationException)3 Versioned (io.atomix.utils.time.Versioned)2 Preconditions.checkNotNull (com.google.common.base.Preconditions.checkNotNull)1 Lists (com.google.common.collect.Lists)1 Maps (com.google.common.collect.Maps)1 Hashing (com.google.common.hash.Hashing)1 AsyncDocumentTree (io.atomix.core.tree.AsyncDocumentTree)1 DocumentTree (io.atomix.core.tree.DocumentTree)1 DocumentTreeBuilder (io.atomix.core.tree.DocumentTreeBuilder)1 NoSuchDocumentPathException (io.atomix.core.tree.NoSuchDocumentPathException)1 PrimitiveManagementService (io.atomix.primitive.PrimitiveManagementService)1 PrimitiveProtocol (io.atomix.primitive.PrimitiveProtocol)1 Partition (io.atomix.primitive.partition.Partition)1 PartitionGroup (io.atomix.primitive.partition.PartitionGroup)1 PartitionId (io.atomix.primitive.partition.PartitionId)1 Partitioner (io.atomix.primitive.partition.Partitioner)1 Futures (io.atomix.utils.concurrent.Futures)1 Map (java.util.Map)1 CompletableFuture (java.util.concurrent.CompletableFuture)1