# Class DataTree

java.lang.Object
org.apache.zookeeper.server.DataTree

public class DataTree extends Object
This class maintains the tree data structure. It doesn't have any networking or client connection code in it so that it can be tested in a standalone way.

The tree maintains two parallel data structures: a hashtable that maps from full paths to DataNodes and a tree of DataNodes. All accesses to a path is through the hashtable. The tree is traversed only when serializing to disk.

## Nested Class Summary

Nested Classes
Modifier and Type
Class
Description
`static class`
`DataTree.ProcessTxnResult`
`class`
`DataTree.ZxidDigest`
A helper class to maintain the digest meta associated with specific zxid.

## Field Summary

Fields
Modifier and Type
Field
Description
`static final int`
`DIGEST_LOG_INTERVAL`
`static final int`
`DIGEST_LOG_LIMIT`
`long`
`lastProcessedZxid`
`static final int`
`STAT_OVERHEAD_BYTES`
over-the-wire size of znode stat.

## Constructor Summary

Constructors
Constructor
Description
`DataTree()`

## Method Summary

Modifier and Type
Method
Description
`int`
`aclCacheSize()`
`void`
`addConfigNode()`
create a /zookeeper/config node for maintaining the configuration (membership and quorum system) info for zookeeper
`void`
`addDigestWatcher(DigestWatcher digestWatcher)`
Add digest mismatch event handler.
`void`
`addWatch(String basePath, Watcher watcher, int mode)`
`long`
`approximateDataSize()`
Get the size of the nodes based on path and data length.
`long`
`cachedApproximateDataSize()`
`boolean`
`compareDigest(TxnHeader header, Record txn, TxnDigest digest)`
Compares the digest of the tree with the digest present in transaction digest.
`void`
`compareSnapshotDigests(long zxid)`
Compares the actual tree's digest with that in the snapshot.
`boolean`
`containsWatcher(String path, Watcher.WatcherType type, Watcher watcher)`
`static void`
`copyStat(Stat from, Stat to)`
Deprecated.
`static void`
`copyStatPersisted(StatPersisted from, StatPersisted to)`
Deprecated.
`void`
`createNode(String path, byte[] data, List<ACL> acl, long ephemeralOwner, int parentCVersion, long zxid, long time)`
Add a new node to the DataTree.
`void`
`createNode(String path, byte[] data, List<ACL> acl, long ephemeralOwner, int parentCVersion, long zxid, long time, Stat outputStat)`
Add a new node to the DataTree.
`static StatPersisted`
`createStat(long zxid, long time, long ephemeralOwner)`
Create a node stat from the given params.
`void`
`deleteNode(String path, long zxid)`
remove the path from the datatree
`void`
`deserialize(InputArchive ia, String tag)`
`boolean`
`deserializeLastProcessedZxid(InputArchive ia)`
Deserializes the lastProcessedZxid from the input stream and updates the lastProcessedZxid field.
`boolean`
`deserializeZxidDigest(InputArchive ia, long startZxidOfSnapshot)`
Deserializing the zxid digest from the input stream and update the digestFromLoadedSnapshot.
`void`
`dumpEphemerals(PrintWriter writer)`
Write a text dump of all the ephemerals in the datatree.
`void`
`dumpWatches(PrintWriter writer, boolean byPath)`
Write a text dump of all the watches on the datatree.
`void`
`dumpWatchesSummary(PrintWriter writer)`
Summary of the watches on the datatree.
`List<ACL>`
`getACL(String path, Stat stat)`
`List<ACL>`
`getACL(DataNode node)`
`int`
`getAllChildrenNumber(String path)`
`List<String>`
`getChildren(String path, Stat stat, Watcher watcher)`
`Set<String>`
`getContainers()`
`byte[]`
`getData(String path, Stat stat, Watcher watcher)`
`DataTree.ZxidDigest`
`getDigestFromLoadedSnapshot()`
`List<DataTree.ZxidDigest>`
`getDigestLog()`
Return all the digests in the historical digest list.
`Map<Long, Set<String>>`
`getEphemerals()`
Returns a mapping of session ID to ephemeral znodes.
`Set<String>`
`getEphemerals(long sessionId)`
`int`
`getEphemeralsCount()`
`DataTree.ZxidDigest`
`getLastProcessedZxidDigest()`
`String`
`getMaxPrefixWithQuota(String path)`
If there is a quota set, return the appropriate prefix for that quota Else return null
`DataNode`
`getNode(String path)`
`int`
`getNodeCount()`
`ReferenceCountedACLCache`
`getReferenceCountedAclCache()`
`Collection<Long>`
`getSessions()`
`long`
`getTreeDigest()`
`Set<String>`
`getTtls()`
`int`
`getWatchCount()`
`WatchesReport`
`getWatches()`
Returns a watch report.
`WatchesPathReport`
`getWatchesByPath()`
Returns a watch report by path.
`WatchesSummary`
`getWatchesSummary()`
Returns a watch summary.
`DataTree.ProcessTxnResult`
`processTxn(TxnHeader header, Record txn)`
`DataTree.ProcessTxnResult`
`processTxn(TxnHeader header, Record txn, boolean isSubTxn)`
`DataTree.ProcessTxnResult`
`processTxn(TxnHeader header, Record txn, TxnDigest digest)`
`void`
`removeCnxn(Watcher watcher)`
`boolean`
`removeWatch(String path, Watcher.WatcherType type, Watcher watcher)`
`void`
`reportDigestMismatch(long zxid)`
Reports any mismatch in the transaction digest.
`void`
`serialize(OutputArchive oa, String tag)`
`void`
`serializeAcls(OutputArchive oa)`
`boolean`
`serializeLastProcessedZxid(OutputArchive oa)`
Serializes the lastProcessedZxid so we can get it from snapshot instead the snapshot file name.
`void`
`serializeNodeData(OutputArchive oa, String path, DataNode node)`
`void`
`serializeNodes(OutputArchive oa)`
`boolean`
`serializeZxidDigest(OutputArchive oa)`
Serializing the digest to snapshot, this is done after the data tree is being serialized, so when we replay the txns, and it hits this zxid we know we should be in a non-fuzzy state, and have the same digest.
`Stat`
`setACL(String path, List<ACL> acl, int version)`
`void`
`setCversionPzxid(String path, int newCversion, long zxid)`
This method sets the Cversion and Pzxid for the specified node to the values passed as arguments.
`Stat`
`setData(String path, byte[] data, int version, long zxid, long time)`
`void`
`setWatches(long relativeZxid, List<String> dataWatches, List<String> existWatches, List<String> childWatches, List<String> persistentWatches, List<String> persistentRecursiveWatches, Watcher watcher)`
`void`
`shutdownWatcher()`
`Stat`
`statNode(String path, Watcher watcher)`
`void`
`updateQuotaStat(String lastPrefix, long bytesDiff, int countDiff)`
update the count/bytes of this stat data node

### Methods inherited from class Object

`clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

## Field Details

### STAT_OVERHEAD_BYTES

public static final int STAT_OVERHEAD_BYTES
over-the-wire size of znode stat. Counting the fields of Stat class

See Also:
  - Constant Field Values

### DIGEST_LOG_LIMIT

public static final int DIGEST_LOG_LIMIT

See Also:
  - Constant Field Values

### DIGEST_LOG_INTERVAL

public static final int DIGEST_LOG_INTERVAL

See Also:
  - Constant Field Values

### lastProcessedZxid

public volatile long lastProcessedZxid

## Constructor Details

### DataTree

public DataTree()

## Method Details

### getEphemerals

public Set<String> getEphemerals(long sessionId)

### getContainers

public Set<String> getContainers()

### getTtls

public Set<String> getTtls()

### getSessions

public Collection<Long> getSessions()

### getNode

public DataNode getNode(String path)

### getNodeCount

public int getNodeCount()

### getWatchCount

public int getWatchCount()

### getEphemeralsCount

public int getEphemeralsCount()

### approximateDataSize

public long approximateDataSize()
Get the size of the nodes based on path and data length.

Returns:
  size of the data

### cachedApproximateDataSize

public long cachedApproximateDataSize()

### addConfigNode

public void addConfigNode()
create a /zookeeper/config node for maintaining the configuration (membership and quorum system) info for zookeeper

### copyStatPersisted

@Deprecated public static void copyStatPersisted(StatPersisted from, StatPersisted to)
Deprecated.
Use `StatPersisted.copyFrom(StatPersisted)` instead.

Apache Curator uses it, let's keep it for now to let them and their clients to react.

### copyStat

@Deprecated public static void copyStat(Stat from, Stat to)
Deprecated.
Use `Stat.copyFrom(Stat)` instead.

Apache Curator uses it, let's keep it for now to let them and their clients to react.

### updateQuotaStat

public void updateQuotaStat(String lastPrefix, long bytesDiff, int countDiff)
update the count/bytes of this stat data node

Parameters:
  `lastPrefix` - the path of the node that has a quota.
  `bytesDiff` - the diff to be added to number of bytes
  `countDiff` - the diff to be added to the count

### createNode

public void createNode(String path, byte[] data, List<ACL> acl, long ephemeralOwner, int parentCVersion, long zxid, long time) throws KeeperException.NoNodeException, KeeperException.NodeExistsException
Add a new node to the DataTree.

Parameters:
  `path` - Path for the new node.
  `data` - Data to store in the node.
  `acl` - Node acls
  `ephemeralOwner` - the session id that owns this node. -1 indicates this is not an ephemeral node.
  `zxid` - Transaction ID
  `time` -
Throws:
  `KeeperException.NodeExistsException`
  `KeeperException.NoNodeException`

### createNode

public void createNode(String path, byte[] data, List<ACL> acl, long ephemeralOwner, int parentCVersion, long zxid, long time, Stat outputStat) throws KeeperException.NoNodeException, KeeperException.NodeExistsException
Add a new node to the DataTree.

Parameters:
  `path` - Path for the new node.
  `data` - Data to store in the node.
  `acl` - Node acls
  `ephemeralOwner` - the session id that owns this node. -1 indicates this is not an ephemeral node.
  `zxid` - Transaction ID
  `time` -
  `outputStat` - A Stat object to store Stat output results into.
Throws:
  `KeeperException.NodeExistsException`
  `KeeperException.NoNodeException`

### deleteNode

public void deleteNode(String path, long zxid) throws KeeperException.NoNodeException
remove the path from the datatree

Parameters:
  `path` - the path to of the node to be deleted
  `zxid` - the current zxid
Throws:
  `KeeperException.NoNodeException`

### setData

public Stat setData(String path, byte[] data, int version, long zxid, long time) throws KeeperException.NoNodeException

Throws:
  `KeeperException.NoNodeException`

### getMaxPrefixWithQuota

public String getMaxPrefixWithQuota(String path)
If there is a quota set, return the appropriate prefix for that quota Else return null

Parameters:
  `path` - The ZK path to check for quota
Returns:
  Max quota prefix, or null if none

### addWatch

public void addWatch(String basePath, Watcher watcher, int mode)

### getData

public byte[] getData(String path, Stat stat, Watcher watcher) throws KeeperException.NoNodeException

Throws:
  `KeeperException.NoNodeException`

### statNode

public Stat statNode(String path, Watcher watcher) throws KeeperException.NoNodeException

Throws:
  `KeeperException.NoNodeException`

### getChildren

public List<String> getChildren(String path, Stat stat, Watcher watcher) throws KeeperException.NoNodeException

Throws:
  `KeeperException.NoNodeException`

### getAllChildrenNumber

public int getAllChildrenNumber(String path)

### setACL

public Stat setACL(String path, List<ACL> acl, int version) throws KeeperException.NoNodeException

Throws:
  `KeeperException.NoNodeException`

### getACL

public List<ACL> getACL(String path, Stat stat) throws KeeperException.NoNodeException

Throws:
  `KeeperException.NoNodeException`

### getACL

public List<ACL> getACL(DataNode node)

### aclCacheSize

public int aclCacheSize()

### processTxn

public DataTree.ProcessTxnResult processTxn(TxnHeader header, Record txn, TxnDigest digest)

### processTxn

public DataTree.ProcessTxnResult processTxn(TxnHeader header, Record txn)

### processTxn

public DataTree.ProcessTxnResult processTxn(TxnHeader header, Record txn, boolean isSubTxn)

### serializeNodeData

public void serializeNodeData(OutputArchive oa, String path, DataNode node) throws IOException

Throws:
  `IOException`

### serializeAcls

public void serializeAcls(OutputArchive oa) throws IOException

Throws:
  `IOException`

### serializeNodes

public void serializeNodes(OutputArchive oa) throws IOException

Throws:
  `IOException`

### serialize

public void serialize(OutputArchive oa, String tag) throws IOException

Throws:
  `IOException`

### deserialize

public void deserialize(InputArchive ia, String tag) throws IOException

Throws:
  `IOException`

### dumpWatchesSummary

public void dumpWatchesSummary(PrintWriter writer)
Summary of the watches on the datatree.

Parameters:
  `writer` - the output to write to

### dumpWatches

public void dumpWatches(PrintWriter writer, boolean byPath)
Write a text dump of all the watches on the datatree. Warning, this is expensive, use sparingly!

Parameters:
  `writer` - the output to write to

### getWatches

public WatchesReport getWatches()
Returns a watch report.

Returns:
  watch report
See Also:
  - `WatchesReport`

### getWatchesByPath

public WatchesPathReport getWatchesByPath()
Returns a watch report by path.

Returns:
  watch report
See Also:
  - `WatchesPathReport`

### getWatchesSummary

public WatchesSummary getWatchesSummary()
Returns a watch summary.

Returns:
  watch summary
See Also:
  - `WatchesSummary`

### dumpEphemerals

public void dumpEphemerals(PrintWriter writer)
Write a text dump of all the ephemerals in the datatree.

Parameters:
  `writer` - the output to write to

### shutdownWatcher

public void shutdownWatcher()

### getEphemerals

public Map<Long, Set<String>> getEphemerals()
Returns a mapping of session ID to ephemeral znodes.

Returns:
  map of session ID to sets of ephemeral znodes

### removeCnxn

public void removeCnxn(Watcher watcher)

### setWatches

public void setWatches(long relativeZxid, List<String> dataWatches, List<String> existWatches, List<String> childWatches, List<String> persistentWatches, List<String> persistentRecursiveWatches, Watcher watcher)

### setCversionPzxid

public void setCversionPzxid(String path, int newCversion, long zxid) throws KeeperException.NoNodeException
This method sets the Cversion and Pzxid for the specified node to the values passed as arguments. The values are modified only if newCversion is greater than the current Cversion. A NoNodeException is thrown if a znode for the specified path is not found.

Parameters:
  `path` - Full path to the znode whose Cversion needs to be modified. A "/" at the end of the path is ignored.
  `newCversion` - Value to be assigned to Cversion
  `zxid` - Value to be assigned to Pzxid
Throws:
  `KeeperException.NoNodeException` - If znode not found.

### containsWatcher

public boolean containsWatcher(String path, Watcher.WatcherType type, Watcher watcher)

### removeWatch

public boolean removeWatch(String path, Watcher.WatcherType type, Watcher watcher)

### getReferenceCountedAclCache

public ReferenceCountedACLCache getReferenceCountedAclCache()

### serializeZxidDigest

public boolean serializeZxidDigest(OutputArchive oa) throws IOException
Serializing the digest to snapshot, this is done after the data tree is being serialized, so when we replay the txns, and it hits this zxid we know we should be in a non-fuzzy state, and have the same digest.

Parameters:
  `oa` - the output stream to write to
Returns:
  true if the digest is serialized successfully
Throws:
  `IOException`

### deserializeZxidDigest

public boolean deserializeZxidDigest(InputArchive ia, long startZxidOfSnapshot) throws IOException
Deserializing the zxid digest from the input stream and update the digestFromLoadedSnapshot.

Parameters:
  `ia` - the input stream to read from
  `startZxidOfSnapshot` - the zxid of snapshot file
Returns:
  the true if it deserialized successfully
Throws:
  `IOException`

### serializeLastProcessedZxid

public boolean serializeLastProcessedZxid(OutputArchive oa) throws IOException
Serializes the lastProcessedZxid so we can get it from snapshot instead the snapshot file name. This is needed for performing snapshot and restore via admin server commands.

Parameters:
  `oa` - the output stream to write to
Returns:
  true if the lastProcessedZxid is serialized successfully, otherwise false
Throws:
  `IOException` - if there is an I/O error

### deserializeLastProcessedZxid

public boolean deserializeLastProcessedZxid(InputArchive ia) throws IOException
Deserializes the lastProcessedZxid from the input stream and updates the lastProcessedZxid field.

Parameters:
  `ia` - the input stream to read from
Returns:
  true if lastProcessedZxid is deserialized successfully, otherwise false
Throws:
  `IOException` - if there is an I/O error

### compareSnapshotDigests

public void compareSnapshotDigests(long zxid)
Compares the actual tree's digest with that in the snapshot. Resets digestFromLoadedSnapshot after comparison.

Parameters:
  `zxid` - zxid

### compareDigest

public boolean compareDigest(TxnHeader header, Record txn, TxnDigest digest)
Compares the digest of the tree with the digest present in transaction digest. If there is any error, logs and alerts the watchers.

Parameters:
  `header` - transaction header being applied
  `txn` - transaction
  `digest` - transaction digest
Returns:
  false if digest in the txn doesn't match what we have now in the data tree

### reportDigestMismatch

public void reportDigestMismatch(long zxid)
Reports any mismatch in the transaction digest.

Parameters:
  `zxid` - zxid for which the error is being reported.

### getTreeDigest

public long getTreeDigest()

### getLastProcessedZxidDigest

public DataTree.ZxidDigest getLastProcessedZxidDigest()

### getDigestFromLoadedSnapshot

public DataTree.ZxidDigest getDigestFromLoadedSnapshot()

### addDigestWatcher

public void addDigestWatcher(DigestWatcher digestWatcher)
Add digest mismatch event handler.

Parameters:
  `digestWatcher` - the handler to add

### getDigestLog

public List<DataTree.ZxidDigest> getDigestLog()
Return all the digests in the historical digest list.

### createStat

public static StatPersisted createStat(long zxid, long time, long ephemeralOwner)
Create a node stat from the given params.

Parameters:
  `zxid` - the zxid associated with the txn
  `time` - the time when the txn is created
  `ephemeralOwner` - the owner if the node is an ephemeral
Returns:
  the stat