/** * @return a Set of child node names that hang directly off the backup tree root, or null if the backup tree root doesn't exist. */ protected Set<Object> getBackupRoots() { InternalNode backupSubtree = dataContainer.peekInternalNode(BuddyManager.BUDDY_BACKUP_SUBTREE_FQN, false); if (backupSubtree == null) return null; return backupSubtree.getChildrenNames(); }
private InternalNode lookupInAllScopes(InvocationContext ctx, Fqn fqn) { ReadCommittedNode nodeSPI = (ReadCommittedNode) lookupForEviction(ctx, fqn); if (nodeSPI == null) { return dataContainer.peekInternalNode(fqn, true); } return nodeSPI.getDelegationTarget(); }
public boolean lockAllAndRecord(Fqn fqn, LockType lockType, InvocationContext ctx) throws InterruptedException { return lockRecursively(dataContainer.peekInternalNode(fqn, false), ctx.getLockAcquisitionTimeout(lockAcquisitionTimeout), false, ctx); }
@Override public void markForUpdate(DataContainer container, boolean writeSkewCheck) { if (isFlagSet(CHANGED)) return; // already copied Fqn fqn = getFqn(); // mark node as changed. setFlag(CHANGED); if (writeSkewCheck) { // check for write skew. InternalNode underlyingNode = container.peekInternalNode(fqn, true); if (underlyingNode != null && underlyingNode != node) { String errormsg = new StringBuilder().append("Detected write skew on Fqn [").append(fqn).append("]. Another process has changed the node since we last read it!").toString(); if (log.isWarnEnabled()) log.warn(errormsg + ". Unable to copy node for update."); throw new DataVersioningException(errormsg); } } // make a backup copy backup = node; node = copyNode(backup); }
private InternalNode findNode(InvocationContext ctx, Fqn fqn) { ReadCommittedNode n = (ReadCommittedNode) ctx.lookUpNode(fqn); if (n == null || n.isNullNode()) { return dataContainer.peekInternalNode(fqn, true); } else { return n.getDelegationTarget(); } }
/** * Tests if locking the parent is necessary when locking a specific node. * * @param parent Fqn of parent node to check * @param ctx invocation context * @return true if parent lock is needed, false otherwise. */ private boolean isParentLockNeeded(Fqn parent, InvocationContext ctx) { ReadCommittedNode parentNodeTmp = (ReadCommittedNode) ctx.lookUpNode(parent); InternalNode in = parentNodeTmp == null ? dataContainer.peekInternalNode(parent, true) : parentNodeTmp.getDelegationTarget(); return isParentLockNeeded(in); } }
@Override public Object visitGetChildrenNamesCommand(InvocationContext ctx, GetChildrenNamesCommand command) throws Throwable { Fqn fqn = command.getFqn(); if (fqn != null) { loadIfNeeded(ctx, fqn, null, false, false, false, false, false, true, true); loadChildren(fqn, dataContainer.peekInternalNode(fqn, true), false, false, ctx); } return invokeNextInterceptor(ctx, command); }
@SuppressWarnings("unchecked") private void handleRecursiveEvict(InvocationContext ctx, EvictCommand command) throws InterruptedException { List<Fqn> fqnsToEvict; if (command.getFqn().isRoot()) { // if this is the root node, do not attempt to lock this for writing but instead just get all direct children of root. Map<Object, InternalNode> children = dataContainer.peekInternalNode(Fqn.ROOT, false).getChildrenMap(); if (!children.isEmpty()) { fqnsToEvict = new LinkedList<Fqn>(); // lock recursively. for (InternalNode child : children.values()) { fqnsToEvict.addAll(helper.wrapNodesRecursivelyForRemoval(ctx, child.getFqn())); } } else { fqnsToEvict = Collections.emptyList(); } } else { // lock current node recursively. fqnsToEvict = helper.wrapNodesRecursivelyForRemoval(ctx, command.getFqn()); } // set these in the evict command so that the command is aware of what needs to be evicted. command.setNodesToEvict(fqnsToEvict); }
@Override @SuppressWarnings("unchecked") public InternalNode<K, V> createChildNode(Fqn fqn, InternalNode<K, V> parent, InvocationContext ctx, boolean attachToParent) { InternalNode<K, V> child; if (fqn == null) throw new IllegalArgumentException("null child fqn"); child = dataContainer.peekInternalNode(fqn, false); if (child == null) { cache.getNotifier().notifyNodeCreated(fqn, true, ctx); InternalNode<K, V> newChild = createInternalNode(fqn); if (attachToParent) parent.addChild(newChild); // addChild actually succeeded! child = newChild; if (trace) log.trace("Created new child with fqn [" + fqn + "]"); // notify if we actually created a new child cache.getNotifier().notifyNodeCreated(fqn, false, ctx); } return child; } }
@SuppressWarnings("unchecked") private void handleNonrecursiveEvict(InvocationContext ctx, EvictCommand command) throws InterruptedException { if (command.getFqn().isRoot()) { // if this is the root node, do not attempt to lock this for writing but instead just get all direct children of root. Map<Object, InternalNode> children = dataContainer.peekInternalNode(Fqn.ROOT, false).getChildrenMap(); if (!children.isEmpty()) { for (InternalNode child : children.values()) { helper.wrapNodeForWriting(ctx, child.getFqn(), true, false, false, true, true); } } } else { // just wrap the node for writing. Do not create if absent. helper.wrapNodeForWriting(ctx, command.getFqn(), true, false, false, true, true); } }
retval = container.peekInternalNode(parentFqn, false);