2021SC@SDUSC
DataNode
zookeeper中的数据节点类
这个类包含了zookeeper的DataTree模型中一个节点相关的数据。
成员变量:
// 我们前文介绍过的一个节点的digest属性,在zookeeper
//中计算digest的实现类里是通过path, data和stat计算得到的
private volatile long digest;
// 记录节点的digest(digest)是否计算好了
//可以看作是空间换时间,优化了程序性能,不必总是重新计算digest
volatile boolean digestCached;
//该数据节点存的数据,以字节数组的形式
byte[] data;
//权限
Long acl;
//我们前文介绍过的一个节点的stat属性
public StatPersisted stat;
//该节点的子节点路径的集合,并且这个路径不是完整的
//而是只包含路径的最后部分(排除了祖先节点那部分的路径)
private Set<String> children = null;
//存空集,只用于该类的getChildren函数(见下方)
private static final Set<String> EMPTY_SET = Collections.emptySet();
构造函数:
//默认构造器
DataNode() {
}
//参数为节点要存储的数据,节点的acl权限,节点的stat信息
public DataNode(byte[] data, Long acl, StatPersisted stat) {
this.data = data;
this.acl = acl;
this.stat = stat;
}
child变量的相关操作:
//给子节点集合(children)这个变量,插入新的子节点的路径
public synchronized boolean addChild(String child) {
if (children == null) {
// let's be conservative on the typical number of children
children = new HashSet<String>(8);
}
return children.add(child);
}
//给子节点集合(children)这个变量,移出子节点的路径
public synchronized boolean removeChild(String child) {
if (children == null) {
return false;
}
return children.remove(child);
}
//设置子节点集合(children)这个变量
public synchronized void setChildren(HashSet<String> children) {
this.children = children;
}
//获取子节点集合(children)这个变量的值
//注意children为null时,返回的不是空对象而是空集
//集合不为空时,返回的是不可修改视图
public synchronized Set<String> getChildren() {
if (children == null) {
return EMPTY_SET;
}
return Collections.unmodifiableSet(children);
}
//复制stat
public synchronized void copyStat(Stat to) {
to.setAversion(stat.getAversion());
to.setCtime(stat.getCtime());
to.setCzxid(stat.getCzxid());
to.setMtime(stat.getMtime());
to.setMzxid(stat.getMzxid());
to.setPzxid(stat.getPzxid());
to.setVersion(stat.getVersion());
to.setEphemeralOwner(getClientEphemeralOwner(stat));
to.setDataLength(data == null ? 0 : data.length);
int numChildren = 0;
if (this.children != null) {
numChildren = children.size();
}
to.setCversion(stat.getCversion() * 2 - numChildren);
to.setNumChildren(numChildren);
}
//临时节点判断
private static long getClientEphemeralOwner(StatPersisted stat) {
EphemeralType ephemeralType = EphemeralType.get(stat.getEphemeralOwner());
if (ephemeralType != EphemeralType.NORMAL) {
return 0;
}
return stat.getEphemeralOwner();
}
剩下的几个函数就比较常规了
序列化反序列化函数,digest,digestCached的get/set函数(digestCached的get函数此处命名是isDigestCached),data的get函数(注意要同步,synchronzed关键字)。