- // Ready to change the context now, make sure no operations are running
- rwLock.writeLock().lock();
- try {
- Preconditions.checkState(c.getBeforeRoot() == rootNode,
- String.format("Store tree %s and candidate base %s differ.", rootNode, c.getBeforeRoot()));
- this.rootNode = c.getAfterRoot();
- } finally {
- rwLock.writeLock().unlock();
- }
+ final TreeNode newRoot = c.getTipRoot();
+ DataTreeState currentState;
+ DataTreeState newState;
+ do {
+ currentState = currentState();
+ final TreeNode currentRoot = currentState.getRoot();
+ LOG.debug("Updating datastore from {} to {}", currentRoot, newRoot);
+
+ final TreeNode oldRoot = c.getBeforeRoot();
+ if (oldRoot != currentRoot) {
+ final String oldStr = simpleToString(oldRoot);
+ final String currentStr = simpleToString(currentRoot);
+ throw new IllegalStateException("Store tree " + currentStr + " and candidate base " + oldStr
+ + " differ.");
+ }
+
+ newState = currentState.withRoot(newRoot);
+ LOG.trace("Updated state from {} to {}", currentState, newState);
+ // TODO: can we lower this to compareAndSwapRelease?
+ } while (!STATE.compareAndSet(this, currentState, newState));
+ }
+
+ private static String simpleToString(final Object obj) {
+ return obj.getClass().getName() + "@" + Integer.toHexString(obj.hashCode());
+ }
+
+ private DataTreeState currentState() {
+ return (DataTreeState) STATE.getAcquire(this);
+ }
+
+ @Override
+ public YangInstanceIdentifier getRootPath() {
+ return treeConfig.getRootPath();
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("object", super.toString())
+ .add("config", treeConfig)
+ .add("state", currentState())
+ .toString();
+ }
+
+ @Override
+ protected TreeNode getTipRoot() {
+ return currentState().getRoot();