internal object add(ulong key, int keyLength, object obj) { object prevObj; #endif if (key == this.key && keyLength == this.keyLength) { Modify(); prevObj = this.obj; this.obj = obj; return(prevObj); } int keyLengthCommon = getCommonPartLength(key, keyLength, this.key, this.keyLength); int keyLengthDiff = this.keyLength - keyLengthCommon; ulong keyCommon = key >> (keyLength - keyLengthCommon); ulong keyDiff = this.key - (keyCommon << keyLengthDiff); if (keyLengthDiff > 0) { Modify(); PTrieNode newNode = new PTrieNode(keyDiff, keyLengthDiff, this.obj); newNode.childZero = childZero; newNode.childOne = childOne; this.key = keyCommon; this.keyLength = keyLengthCommon; this.obj = null; if (firstBit(keyDiff, keyLengthDiff) == 1) { childZero = null; childOne = newNode; } else { childZero = newNode; childOne = null; } } if (keyLength > keyLengthCommon) { keyLengthDiff = keyLength - keyLengthCommon; keyDiff = key - (keyCommon << keyLengthDiff); if (firstBit(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 { prevObj = this.obj; this.obj = obj; return(prevObj); } }
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); } }