예제 #1
0
 /*
  * stack contains all ancestors of the node, stack.peek() is its parent.
  */
 private void mutateUp(@NotNull final Deque<ChildReferenceTransient> stack, MutableNode node) {
   while (!stack.isEmpty()) {
     final ChildReferenceTransient parent = stack.pop();
     final MutableNode mutableParent = parent.mutate(this);
     mutableParent.setChild(parent.firstByte, node);
     node = mutableParent;
   }
 }
예제 #2
0
 @Override
 public boolean add(@NotNull final ByteIterable key, @NotNull final ByteIterable value) {
   final ByteIterator it = key.iterator();
   NodeBase node = root;
   MutableNode mutableNode = null;
   final Deque<ChildReferenceTransient> stack = new ArrayDeque<>();
   while (true) {
     final NodeBase.MatchResult matchResult = node.matchesKeySequence(it);
     final int matchingLength = matchResult.matchingLength;
     if (matchingLength < 0) {
       final MutableNode prefix =
           node.getMutableCopy(this).splitKey(-matchingLength - 1, matchResult.keyByte);
       if (matchResult.hasNext) {
         prefix.hang(matchResult.nextByte, it).setValue(value);
       } else {
         prefix.setValue(value);
       }
       if (stack.isEmpty()) {
         root = new MutableRoot(prefix, root.sourceAddress);
       } else {
         final ChildReferenceTransient parent = stack.pop();
         mutableNode = parent.mutate(this);
         mutableNode.setChild(parent.firstByte, prefix);
       }
       break;
     }
     if (!it.hasNext()) {
       if (node.hasValue()) {
         return false;
       }
       mutableNode = node.getMutableCopy(this);
       mutableNode.setValue(value);
       break;
     }
     final byte nextByte = it.next();
     final NodeBase child = node.getChild(this, nextByte);
     if (child == null) {
       mutableNode = node.getMutableCopy(this);
       if (mutableNode.hasChildren() || mutableNode.hasKey() || mutableNode.hasValue()) {
         mutableNode.hang(nextByte, it).setValue(value);
       } else {
         mutableNode.setKeySequence(new ArrayByteIterable(nextByte, it));
         mutableNode.setValue(value);
       }
       break;
     }
     stack.push(new ChildReferenceTransient(nextByte, node));
     node = child;
   }
   ++size;
   mutateUp(stack, mutableNode);
   TreeCursorMutable.notifyCursors(this);
   return true;
 }