Esempio n. 1
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);
                }
            }
Esempio n. 2
0
            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);
            }