internal IPersistent add(ulong key, int keyLength, IPersistent obj) { if (key == this.key && keyLength == this.keyLength) { Modify(); // the new is matched exactly by this node's key, so just replace the node object IPersistent prevObj = this.obj; this.obj = obj; return(prevObj); } int keyLengthCommon = getCommonPart(key, keyLength, this.key, this.keyLength); int keyLengthDiff = this.keyLength - keyLengthCommon; ulong keyCommon = key >> (keyLength - keyLengthCommon); ulong keyDiff = this.key - (keyCommon << keyLengthDiff); // process diff with this node's key, if any if (keyLengthDiff > 0) { Modify(); // create a new node with the diff PTrieNode newNode = new PTrieNode(keyDiff, keyLengthDiff, this.obj); // transfer infos of this node to the new node newNode.childZero = childZero; newNode.childOne = childOne; // update this node to hold common part this.key = keyCommon; this.keyLength = keyLengthCommon; this.obj = null; // and set the new node as child of this node if (firstDigit(keyDiff, keyLengthDiff) == 1) { childZero = null; childOne = newNode; } else { childZero = newNode; childOne = null; } } // process diff with the new key, if any if (keyLength > keyLengthCommon) { // get diff with the new key keyLengthDiff = keyLength - keyLengthCommon; keyDiff = key - (keyCommon << keyLengthDiff); // get which child we use as insertion point and do insertion (recursive) if (firstDigit(keyDiff, keyLengthDiff) == 1) { if (childOne != null) { return(childOne.add(keyDiff, keyLengthDiff, obj)); } else { Modify(); childOne = new PTrieNode(keyDiff, keyLengthDiff, obj); return(null); } } else { if (childZero != null) { return(childZero.add(keyDiff, keyLengthDiff, obj)); } else { Modify(); childZero = new PTrieNode(keyDiff, keyLengthDiff, obj); return(null); } } } else { // the new key was containing within this node's original key, so just set this node as terminator IPersistent prevObj = this.obj; this.obj = obj; return(prevObj); } }
internal T remove(ulong key, int keyLength) { T obj; if (keyLength < this.keyLength) { return(null); } if (key == this.key && keyLength == this.keyLength) { obj = this.obj; this.obj = null; return(obj); } int keyLengthCommon = getCommonPart(key, keyLength, this.key, this.keyLength); int keyLengthDiff = keyLength - keyLengthCommon; ulong keyCommon = key >> keyLengthDiff; ulong keyDiff = key - (keyCommon << keyLengthDiff); if (firstDigit(keyDiff, keyLengthDiff) == 1) { if (childOne == null) { return(null); } obj = childOne.findBestMatch(keyDiff, keyLengthDiff); if (obj == null) { return(null); } if (childOne.isNotUsed()) { Modify(); childOne.Deallocate(); childOne = null; } return(obj); } if (childZero == null) { return(null); } obj = childZero.findBestMatch(keyDiff, keyLengthDiff); if (obj == null) { return(null); } if (childZero.isNotUsed()) { Modify(); childZero.Deallocate(); childZero = null; } return(obj); }