예제 #1
0
            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);
                }
            }
예제 #2
0
            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);
                }
            }