package edu.uw.zookeeper.data;
import static com.google.common.base.Preconditions.checkNotNull;
import java.lang.reflect.Constructor;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.zookeeper.KeeperException;
import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import edu.uw.zookeeper.common.Processors;
import edu.uw.zookeeper.common.Reference;
import edu.uw.zookeeper.data.ZNodeName;
import edu.uw.zookeeper.protocol.Message;
import edu.uw.zookeeper.protocol.ProtocolRequestMessage;
import edu.uw.zookeeper.protocol.SessionRequest;
import edu.uw.zookeeper.protocol.proto.*;
import edu.uw.zookeeper.server.ByOpcodeTxnRequestProcessor;
public class ZNodeNode extends AbstractNameTrie.SimpleNode<ZNodeNode> {
public static ZNodeNode root() {
return root(ZNodeState.defaults());
}
public static ZNodeNode root(ZNodeState state) {
NameTrie.Pointer<ZNodeNode> pointer = SimpleLabelTrie.strongPointer(EmptyZNodeLabel.getInstance(), null);
return new ZNodeNode(
pointer,
state);
}
public static ZNodeNode child(ZNodeLabel label, ZNodeNode parent, ZNodeState state) {
NameTrie.Pointer<ZNodeNode> pointer = SimpleLabelTrie.weakPointer(label, parent);
return new ZNodeNode(
pointer,
state);
}
private final ZNodeState state;
protected ZNodeNode(NameTrie.Pointer<? extends ZNodeNode> parent, ZNodeState state) {
super(SimpleLabelTrie.pathOf(parent), parent, Maps.<ZNodeName, ZNodeNode>newHashMap());
this.state = state;
}
public ZNodeState state() {
return state;
}
public Stats.ImmutableStat asStat() {
int dataLength = state.getData().getDataLength();
int numChildren = size();
return Stats.ImmutableStat.copyOf(Stats.CompositeStatGetter.of(
state.asStatPersisted(), dataLength, numChildren));
}
@Override
public String toString() {
return MoreObjects.toStringHelper("")
.add("path", path())
.add("children", keySet())
.add("state", state())
.toString();
}
public static interface Operator<V extends Records.Response> extends Reference<NameTrie<ZNodeNode>>, Processors.CheckedProcessor<TxnOperation.Request<?>, V, KeeperException> {
}
public static abstract class AbstractProcessor<V> implements Processors.CheckedProcessor<TxnOperation.Request<?>, V, KeeperException>, Reference<NameTrie<ZNodeNode>> {
public static ZNodePath getPath(Records.PathGetter record) throws KeeperException.BadArgumentsException {
try {
return ZNodePath.validated(record.getPath());
} catch (IllegalArgumentException e) {
throw new KeeperException.BadArgumentsException(record.getPath());
}
}
public static ZNodeNode getNode(NameTrie<ZNodeNode> trie, ZNodeName path) throws KeeperException.NoNodeException {
ZNodeNode node = trie.get(path);
if (node == null) {
throw new KeeperException.NoNodeException(path.toString());
}
return node;
}
protected final NameTrie<ZNodeNode> trie;
protected AbstractProcessor(NameTrie<ZNodeNode> trie) {
this.trie = trie;
}
@Override
public NameTrie<ZNodeNode> get() {
return trie;
}
}
public static abstract class AbstractCreate<V> extends AbstractProcessor<V> {
protected AbstractCreate(NameTrie<ZNodeNode> trie) {
super(trie);
}
@Override
public V apply(TxnOperation.Request<?> request) throws KeeperException {
Records.CreateModeGetter record = (Records.CreateModeGetter) request.record();
ZNodePath path = getPath(record);
if (path.isRoot()) {
throw new KeeperException.BadArgumentsException(path.toString());
}
CreateMode mode = CreateMode.valueOf(record.getFlags());
if (! mode.contains(CreateFlag.SEQUENTIAL) && get().containsKey(path)) {
throw new KeeperException.NodeExistsException(path.toString());
}
ZNodeName parentPath = ((AbsoluteZNodePath) path).parent();
ZNodeNode parent = getNode(get(), parentPath);
if (parent.state().getCreate().isEphemeral()) {
throw new KeeperException.NoChildrenForEphemeralsException(parentPath.toString());
}
return doCreate(request, record, mode, parent, (AbsoluteZNodePath) path);
}
protected abstract V doCreate(
TxnOperation.Request<?> request,
Records.CreateModeGetter record,
CreateMode mode,
ZNodeNode parent,
AbsoluteZNodePath path);
}
@Operational(OpCode.DELETE)
public static abstract class AbstractDelete<V> extends AbstractProcessor<V> {
protected AbstractDelete(NameTrie<ZNodeNode> trie) {
super(trie);
}
@Override
public V apply(TxnOperation.Request<?> request)
throws KeeperException {
IDeleteRequest record = (IDeleteRequest) request.record();
ZNodePath path = getPath(record);
if (path.isRoot()) {
throw new KeeperException.BadArgumentsException(path.toString());
}
ZNodeNode node = getNode(get(), path);
if (node.size() > 0) {
throw new KeeperException.NotEmptyException(path.toString());
}
if (! node.state().getData().getStat().compareVersion(record.getVersion())) {
throw new KeeperException.BadVersionException(path.toString());
}
ZNodeNode parent = getNode(get(), ((AbsoluteZNodePath) path).parent());
return doDelete(request, record, path, node, parent);
}
protected abstract V doDelete(
TxnOperation.Request<?> request,
IDeleteRequest record,
ZNodeLabelVector path,
ZNodeNode node,
ZNodeNode parent);
}
@Operational(OpCode.SET_DATA)
public static abstract class AbstractSetData<V> extends AbstractProcessor<V> {
protected AbstractSetData(NameTrie<ZNodeNode> trie) {
super(trie);
}
@Override
public V apply(TxnOperation.Request<?> request)
throws KeeperException {
ISetDataRequest record = (ISetDataRequest) request.record();
ZNodeLabelVector path = getPath(record);
ZNodeNode node = getNode(get(), path);
if (! node.state().getData().getStat().compareVersion(record.getVersion())) {
throw new KeeperException.BadVersionException(path.toString());
}
return doSetData(request, record, path, node);
}
protected abstract V doSetData(
TxnOperation.Request<?> request,
ISetDataRequest record,
ZNodeLabelVector path,
ZNodeNode node);
}
public static abstract class Operators {
private Operators() {}
public static Map<OpCode, Processors.CheckedProcessor<TxnOperation.Request<?>, ? extends Records.Response, KeeperException>> of(NameTrie<ZNodeNode> trie) {
return of(trie, Maps.<OpCode, Processors.CheckedProcessor<TxnOperation.Request<?>, ? extends Records.Response, KeeperException>>newEnumMap(OpCode.class));
}
public static Map<OpCode, Processors.CheckedProcessor<TxnOperation.Request<?>, ? extends Records.Response, KeeperException>> of(NameTrie<ZNodeNode> trie, Map<OpCode, Processors.CheckedProcessor<TxnOperation.Request<?>, ? extends Records.Response, KeeperException>> operators) {
for (Class<?> cls: Operators.class.getDeclaredClasses()) {
Operational annotation = cls.getAnnotation(Operational.class);
if (annotation == null) {
continue;
}
if (! Operator.class.isAssignableFrom(cls)) {
continue;
}
Operator<?> operator = null;
for (Constructor<?> ctor: cls.getConstructors()) {
if (ctor.getParameterTypes().length == 1) {
try {
operator = (Operator<?>) ctor.newInstance(trie);
} catch (Exception e) {
throw new AssertionError(e);
}
break;
}
}
assert (operator != null);
for (OpCode opcode: annotation.value()) {
operators.put(opcode, operator);
}
}
return operators;
}
@Operational(OpCode.CHECK)
public static class CheckOperator extends AbstractProcessor<ICheckVersionResponse> implements Operator<ICheckVersionResponse> {
public CheckOperator(NameTrie<ZNodeNode> trie) {
super(trie);
}
@Override
public ICheckVersionResponse apply(TxnOperation.Request<?> request)
throws KeeperException {
ICheckVersionRequest record = (ICheckVersionRequest) request.record();
ZNodeLabelVector path = getPath(record);
ZNodeNode node = getNode(get(), path);
if (! node.state().getData().getStat().compareVersion(record.getVersion())) {
throw new KeeperException.BadVersionException(path.toString());
}
return Operations.Responses.check().setStat(node.asStat()).build();
}
}
@Operational({OpCode.CREATE, OpCode.CREATE2})
public static class CreateOperator extends AbstractCreate<Records.Response> implements Operator<Records.Response> {
public CreateOperator(NameTrie<ZNodeNode> trie) {
super(trie);
}
@Override
protected Records.Response doCreate(
TxnOperation.Request<?> request,
Records.CreateModeGetter record,
CreateMode mode,
ZNodeNode parent,
AbsoluteZNodePath path) {
int cversion = parent.state().getChildren().getAndIncrement(request.zxid());
if (mode.contains(CreateFlag.SEQUENTIAL)) {
path = AbsoluteZNodePath.fromString(Sequential.fromInt(path, cversion).toString());
}
long ephemeralOwner = mode.contains(CreateFlag.EPHEMERAL) ? request.getSessionId() : Stats.CreateStat.ephemeralOwnerNone();
Stats.CreateStat createStat = Stats.CreateStat.of(request.zxid(), request.getTime(), ephemeralOwner);
byte[] bytes = record.getData();
bytes = (bytes == null) ? ZNodeData.emptyBytes() : bytes;
ZNodeData data = ZNodeData.of(Stats.DataStat.initialVersion(request.zxid(), request.getTime()), bytes);
ZNodeAcl acl = ZNodeAcl.initialVersion(Acls.Acl.fromRecordList(record.getAcl()));
Stats.ChildrenStat childrenStat = Stats.ChildrenStat.initialVersion(request.zxid());
ZNodeState state = ZNodeState.of(createStat, data, acl, childrenStat);
ZNodeLabel label = path.label();
ZNodeNode node = ZNodeNode.child(label, parent, state);
parent.put(label, node);
Operations.Responses.Create builder =
Operations.Responses.create().setPath(path);
if (OpCode.CREATE2 == request.record().opcode()) {
builder.setStat(node.asStat());
}
return builder.build();
}
}
@Operational(OpCode.DELETE)
public static class DeleteOperator extends AbstractDelete<IDeleteResponse> implements Operator<IDeleteResponse> {
public DeleteOperator(NameTrie<ZNodeNode> trie) {
super(trie);
}
@Override
protected IDeleteResponse doDelete(
TxnOperation.Request<?> request,
IDeleteRequest record,
ZNodeLabelVector path,
ZNodeNode node,
ZNodeNode parent) {
get().remove(path);
parent.state().getChildren().getAndIncrement(request.zxid());
return Operations.Responses.delete().build();
}
}
@Operational(OpCode.EXISTS)
public static class ExistsOperator extends AbstractProcessor<IExistsResponse> implements Operator<IExistsResponse> {
public ExistsOperator(NameTrie<ZNodeNode> trie) {
super(trie);
}
@Override
public IExistsResponse apply(TxnOperation.Request<?> request)
throws KeeperException {
IExistsRequest record = (IExistsRequest) request.record();
ZNodeLabelVector path = getPath(record);
ZNodeNode node = getNode(get(), path);
return Operations.Responses.exists().setStat(node.asStat()).build();
}
}
@Operational(OpCode.GET_DATA)
public static class GetDataOperator extends AbstractProcessor<IGetDataResponse> implements Operator<IGetDataResponse> {
public GetDataOperator(NameTrie<ZNodeNode> trie) {
super(trie);
}
@Override
public IGetDataResponse apply(TxnOperation.Request<?> request)
throws KeeperException {
IGetDataRequest record = (IGetDataRequest) request.record();
ZNodeLabelVector path = getPath(record);
ZNodeNode node = getNode(get(), path);
return Operations.Responses.getData().setData(node.state().getData().getData()).setStat(node.asStat()).build();
}
}
@Operational(OpCode.SET_DATA)
public static class SetDataOperator extends AbstractSetData<ISetDataResponse> implements Operator<ISetDataResponse> {
public SetDataOperator(NameTrie<ZNodeNode> trie) {
super(trie);
}
@Override
protected ISetDataResponse doSetData(
TxnOperation.Request<?> request,
ISetDataRequest record,
ZNodeLabelVector path,
ZNodeNode node) {
node.state().getData().getStat().getAndIncrement(request.zxid(), request.getTime());
byte[] bytes = record.getData();
bytes = (bytes == null) ? ZNodeData.emptyBytes() : bytes;
node.state().getData().setData(bytes);
return Operations.Responses.setData().setStat(node.asStat()).build();
}
}
@Operational(OpCode.GET_ACL)
public static class GetAclOperator extends AbstractProcessor<IGetACLResponse> implements Operator<IGetACLResponse> {
public GetAclOperator(NameTrie<ZNodeNode> trie) {
super(trie);
}
@Override
public IGetACLResponse apply(TxnOperation.Request<?> request)
throws KeeperException {
IGetACLRequest record = (IGetACLRequest) request.record();
ZNodeLabelVector path = getPath(record);
ZNodeNode node = getNode(get(), path);
return Operations.Responses.getAcl().setAcl(node.state().getAcl().getAcl()).setStat(node.asStat()).build();
}
}
@Operational(OpCode.SET_ACL)
public static class SetAclOperator extends AbstractProcessor<ISetACLResponse> implements Operator<ISetACLResponse> {
public SetAclOperator(NameTrie<ZNodeNode> trie) {
super(trie);
}
@Override
public ISetACLResponse apply(TxnOperation.Request<?> request)
throws KeeperException {
ISetACLRequest record = (ISetACLRequest) request.record();
ZNodeLabelVector path = getPath(record);
ZNodeNode node = getNode(get(), path);
if (! node.state().getAcl().compareVersion(record.getVersion())) {
throw new KeeperException.BadVersionException(path.toString());
}
node.state().getAcl().getAndIncrement();
node.state().getAcl().setAcl(Acls.Acl.fromRecordList(record.getAcl()));
return Operations.Responses.setAcl().setStat(node.asStat()).build();
}
}
@Operational({OpCode.GET_CHILDREN, OpCode.GET_CHILDREN2})
public static class GetChildrenOperator extends AbstractProcessor<Records.Response> implements Operator<Records.Response> {
public GetChildrenOperator(NameTrie<ZNodeNode> trie) {
super(trie);
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public Records.Response apply(TxnOperation.Request<?> request)
throws KeeperException {
ZNodeLabelVector path = getPath((Records.PathGetter) request.record());
ZNodeNode node = getNode(get(), path);
Operations.Responses.GetChildren builder = Operations.Responses.getChildren();
builder.setChildren(ImmutableList.<ZNodeLabel>copyOf((Set) node.keySet()));
if (OpCode.GET_CHILDREN2 == request.record().opcode()) {
builder.setStat(node.asStat());
}
return builder.build();
}
}
@Operational(OpCode.SYNC)
public static class SyncOperator extends AbstractProcessor<ISyncResponse> implements Operator<ISyncResponse> {
public SyncOperator(NameTrie<ZNodeNode> trie) {
super(trie);
}
@Override
public ISyncResponse apply(TxnOperation.Request<?> request)
throws KeeperException {
ISyncRequest record = (ISyncRequest) request.record();
ZNodePath path = getPath(record);
getNode(get(), path);
return Operations.Responses.sync().setPath(path).build();
}
}
}
public static abstract class AbstractUndo implements Processors.UncheckedProcessor<Records.Response, Void> {
protected final TxnOperation.Request<?> request;
protected final NameTrie<ZNodeNode> trie;
protected AbstractUndo(
TxnOperation.Request<?> request,
NameTrie<ZNodeNode> trie) {
this.request = request;
this.trie = trie;
}
}
@Operational({OpCode.CREATE, OpCode.CREATE2})
public static class CreateUndo extends AbstractUndo {
protected final Stats.ChildrenStat parentStat;
public CreateUndo(
Stats.ChildrenStat parentStat,
TxnOperation.Request<?> request,
NameTrie<ZNodeNode> trie) {
super(request, trie);
this.parentStat = parentStat;
}
@Override
public Void apply(Records.Response result) {
ZNodeNode node = trie.get(((Records.PathGetter) result).getPath());
ZNodeNode parent = node.parent().get();
node.remove();
parent.state().setChildren(parentStat);
return null;
}
}
@Operational(OpCode.DELETE)
public static class DeleteUndo extends AbstractUndo {
protected final Stats.ChildrenStat parentStat;
protected final ZNodeState state;
public DeleteUndo(
Stats.ChildrenStat parentStat,
ZNodeState state,
TxnOperation.Request<?> request,
NameTrie<ZNodeNode> trie) {
super(request, trie);
this.parentStat = parentStat;
this.state = state;
}
@Override
public Void apply(Records.Response result) {
AbsoluteZNodePath path = AbsoluteZNodePath.fromString(((Records.PathGetter) request.record()).getPath());
ZNodeNode parent = trie.get(path.parent());
ZNodeLabel label = path.label();
ZNodeNode node = ZNodeNode.child(label, parent, state);
parent.put(label, node);
return null;
}
}
@Operational(OpCode.SET_DATA)
public static class SetDataUndo extends AbstractUndo {
protected final ZNodeData data;
public SetDataUndo(
ZNodeData data,
TxnOperation.Request<?> request,
NameTrie<ZNodeNode> trie) {
super(request, trie);
this.data = data;
}
@Override
public Void apply(Records.Response result) {
ZNodeNode node = trie.get(((Records.PathGetter) request.record()).getPath());
node.state().getData().set(data);
return null;
}
}
@Operational({OpCode.CREATE, OpCode.CREATE2})
public static class CreateCopyState extends AbstractCreate<CreateUndo> {
public CreateCopyState(NameTrie<ZNodeNode> trie) {
super(trie);
}
@Override
protected CreateUndo doCreate(
TxnOperation.Request<?> request,
Records.CreateModeGetter record,
CreateMode mode,
ZNodeNode parent,
AbsoluteZNodePath path) {
return new CreateUndo(
Stats.ChildrenStat.copyOf(parent.state().getChildren()),
request,
get());
}
}
@Operational(OpCode.DELETE)
public static class DeleteCopyState extends AbstractDelete<DeleteUndo> {
public DeleteCopyState(NameTrie<ZNodeNode> trie) {
super(trie);
}
@Override
protected DeleteUndo doDelete(
TxnOperation.Request<?> request,
IDeleteRequest record,
ZNodeLabelVector path,
ZNodeNode node,
ZNodeNode parent) {
return new DeleteUndo(
Stats.ChildrenStat.copyOf(parent.state().getChildren()),
ZNodeState.copyOf(node.state()),
request,
get());
}
}
@Operational(OpCode.SET_DATA)
public static class SetDataCopyState extends AbstractSetData<SetDataUndo> {
public SetDataCopyState(NameTrie<ZNodeNode> trie) {
super(trie);
}
@Override
protected SetDataUndo doSetData(
TxnOperation.Request<?> request,
ISetDataRequest record,
ZNodeLabelVector path,
ZNodeNode node) {
return new SetDataUndo(
ZNodeData.copyOf(node.state().getData()),
request,
get());
}
}
@Operational(OpCode.MULTI)
public static class MultiOperator extends AbstractProcessor<IMultiResponse> implements Operator<IMultiResponse> {
public static MultiOperator of(NameTrie<ZNodeNode> trie) {
return of(trie, ByOpcodeTxnRequestProcessor.create(ImmutableMap.copyOf(Operators.of(trie))));
}
public static MultiOperator of(NameTrie<ZNodeNode> trie, Processors.CheckedProcessor<TxnOperation.Request<?>, ? extends Records.Response, KeeperException> delegate) {
return new MultiOperator(trie, delegate);
}
protected final Map<OpCode, Processors.CheckedProcessor<TxnOperation.Request<?>, ? extends AbstractUndo, KeeperException>> copiers;
protected final Processors.CheckedProcessor<TxnOperation.Request<?>, ? extends Records.Response, KeeperException> delegate;
protected MultiOperator(
NameTrie<ZNodeNode> trie,
Processors.CheckedProcessor<TxnOperation.Request<?>, ? extends Records.Response, KeeperException> delegate) {
super(trie);
this.delegate = delegate;
List<Processors.CheckedProcessor<TxnOperation.Request<?>, ? extends AbstractUndo, KeeperException>> copiers =
ImmutableList.<Processors.CheckedProcessor<TxnOperation.Request<?>, ? extends AbstractUndo, KeeperException>>of(
new CreateCopyState(trie),
new DeleteCopyState(trie),
new SetDataCopyState(trie));
ImmutableMap.Builder<OpCode, Processors.CheckedProcessor<TxnOperation.Request<?>, ? extends AbstractUndo, KeeperException>> builder = ImmutableMap.builder();
for (Processors.CheckedProcessor<TxnOperation.Request<?>, ? extends AbstractUndo, KeeperException> copier: copiers) {
for (OpCode code: copier.getClass().getAnnotation(Operational.class).value()) {
builder.put(code, copier);
}
}
this.copiers = builder.build();
}
@Override
public IMultiResponse apply(TxnOperation.Request<?> input)
throws KeeperException {
IMultiRequest record = (IMultiRequest) input.record();
IErrorResponse error = null;
List<AbstractUndo> undos = Lists.newArrayListWithCapacity(record.size());
List<Records.MultiOpResponse> results = Lists.newArrayListWithCapacity(record.size());
for (Records.MultiOpRequest request: record) {
Records.MultiOpResponse result = null;
if (error != null) {
result = error;
} else {
Message.ClientRequest<?> nestedRequest = ProtocolRequestMessage.of(
input.xid(), request);
TxnOperation.Request<?> nested = TxnRequest.of(
input.getTime(),
input.zxid(),
SessionRequest.of(input.getSessionId(), nestedRequest));
AbstractUndo undo = null;
try {
switch (request.opcode()) {
case CREATE:
case CREATE2:
case DELETE:
case SET_DATA:
undo = copiers.get(request.opcode()).apply(nested);
break;
case CHECK:
break;
default:
throw new AssertionError(String.valueOf(request));
}
result = (Records.MultiOpResponse) delegate.apply(nested);
undos.add(undo);
} catch (KeeperException e) {
result = Operations.Responses.error().setError(e.code()).build();
assert (error == null);
error = Operations.Responses.error().setError(KeeperException.Code.RUNTIMEINCONSISTENCY).build();
for (int i=undos.size()-1; i>=0; --i) {
if (undos.get(i) != null) {
undos.get(i).apply(results.get(i));
}
}
IErrorResponse ok = Operations.Responses.error().setError(KeeperException.Code.OK).build();
for (int i=0; i<undos.size(); ++i) {
results.set(i, ok);
}
}
}
results.add(result);
}
return new IMultiResponse(results);
}
}
public static class ZNodeData {
public static byte[] emptyBytes() {
return new byte[0];
}
public static ZNodeData empty(Stats.DataStat stat) {
return of(stat, emptyBytes());
}
public static ZNodeData of(Stats.DataStat stat, byte[] data) {
return new ZNodeData(stat, data);
}
public static ZNodeData copyOf(ZNodeData value) {
return of(Stats.DataStat.copyOf(value.getStat()),
(value.getData() == null) ? null
: Arrays.copyOf(value.getData(),
value.getData().length));
}
protected final Stats.DataStat stat;
protected byte[] data;
public ZNodeData(Stats.DataStat stat, byte[] data) {
this.stat = stat;
this.data = data;
}
public byte[] getData() {
return data;
}
public void setData(byte[] data) {
this.data = checkNotNull(data);
}
public Stats.DataStat getStat() {
return stat;
}
public int getDataLength() {
return data.length;
}
public void set(ZNodeData value) {
setData(value.getData());
stat.set(value.getStat());
}
@Override
public String toString() {
return MoreObjects.toStringHelper(this)
.add("dataLength", getDataLength())
.add("stat", getStat())
.toString();
}
}
public static class ZNodeAcl implements Records.AclStatSetter {
public static ZNodeAcl anyoneAll() {
return initialVersion(Acls.Definition.ANYONE_ALL.asList());
}
public static ZNodeAcl initialVersion(List<Acls.Acl> acl) {
return of(acl, Stats.initialVersion());
}
public static ZNodeAcl of(List<Acls.Acl> acl, int aversion) {
return new ZNodeAcl(acl, aversion);
}
public static ZNodeAcl copyOf(ZNodeAcl value) {
return of((value.getAcl() == null) ? null
: Lists.newArrayList(value.getAcl()),
value.getAversion());
}
protected int aversion;
protected List<Acls.Acl> acl;
public ZNodeAcl(List<Acls.Acl> acl, int aversion) {
this.aversion = aversion;
this.acl = checkNotNull(acl);
}
public List<Acls.Acl> getAcl() {
return acl;
}
public void setAcl(List<Acls.Acl> acl) {
this.acl = checkNotNull(acl);
}
@Override
public int getAversion() {
return aversion;
}
@Override
public void setAversion(int aversion) {
this.aversion = aversion;
}
public boolean compareVersion(int version) {
return Stats.compareVersion(version, getAversion());
}
public int getAndIncrement() {
int prev = this.aversion;
this.aversion = prev + 1;
return prev;
}
@Override
public String toString() {
return MoreObjects.toStringHelper(this)
.add("acl", getAcl())
.add("aversion", getAversion())
.toString();
}
}
public static class ZNodeState {
public static ZNodeState defaults() {
return defaults(0);
}
public static ZNodeState defaults(long zxid) {
long time = Stats.getTime();
return of(
Stats.CreateStat.nonEphemeral(zxid, time),
ZNodeData.empty(Stats.DataStat.initialVersion(zxid, time)),
ZNodeAcl.anyoneAll(),
Stats.ChildrenStat.initialVersion(zxid));
}
public static ZNodeState copyOf(ZNodeState value) {
return of(Stats.CreateStat.copyOf(value.getCreate()),
ZNodeData.copyOf(value.getData()),
ZNodeAcl.copyOf(value.getAcl()),
Stats.ChildrenStat.copyOf(value.getChildren()));
}
public static ZNodeState of(
Stats.CreateStat createStat,
ZNodeData data,
ZNodeAcl acl,
Stats.ChildrenStat childrenStat) {
return new ZNodeState(createStat, data, acl, childrenStat);
}
protected final Stats.CreateStat create;
protected final ZNodeData data;
protected final ZNodeAcl acl;
protected final Stats.ChildrenStat children;
public ZNodeState(
Stats.CreateStat create,
ZNodeData data,
ZNodeAcl acl,
Stats.ChildrenStat children) {
this.create = create;
this.data = data;
this.acl = acl;
this.children = children;
}
public ZNodeData getData() {
return data;
}
public void setData(ZNodeData data) {
this.data.set(data);
}
public Stats.CreateStat getCreate() {
return create;
}
public ZNodeAcl getAcl() {
return acl;
}
public Stats.ChildrenStat getChildren() {
return children;
}
public void setChildren(Stats.ChildrenStat children) {
this.children.set(children);
}
public Stats.CompositeStatPersistedGetter asStatPersisted() {
return Stats.CompositeStatPersistedGetter.of(
getCreate(), getData().getStat(), getAcl(), getChildren());
}
@Override
public String toString() {
return MoreObjects.toStringHelper(this)
.add("create", getCreate())
.add("children", getChildren())
.add("data", getData())
.add("acl", getData())
.toString();
}
}
}