Пример #1
0
        private long CollectStatistic(HashPage pg, HashStatistic stat, int height)
        {
            long totalHeight = 0;

            stat.nPages += 1;
            if (++height > stat.maxHeight)
            {
                stat.maxHeight = height;
            }
            foreach (object child in pg.items)
            {
                if (child is HashPage)
                {
                    totalHeight += CollectStatistic((HashPage)child, stat, height);
                }
                else if (child != null)
                {
                    int collisionChainLength = 0;
                    for (CollisionItem item = (CollisionItem)child; item != null; item = item.next)
                    {
                        collisionChainLength += 1;
                    }
                    if (stat.maxCollisionChainLength < collisionChainLength)
                    {
                        stat.maxCollisionChainLength = collisionChainLength;
                    }
                    stat.nItems  += collisionChainLength;
                    stat.nChains += 1;
                    totalHeight  += height;
                }
            }
            return(totalHeight);
        }
Пример #2
0
        public override void Clear()
#endif
        {
            if (root != null)
            {
                root.Deallocate();
                root   = null;
                nElems = 0;
                Modify();
            }
        }
Пример #3
0
        public void Remove(object key)
#endif
        {
            HashPage pg = root;

            if (pg != null)
            {
                uint divisor  = 1;
                int  hashCode = key.GetHashCode();
                while (true)
                {
                    int    h     = (int)((uint)hashCode / divisor % pageSize);
                    object child = pg.items[h];
                    if (child is HashPage)
                    {
                        pg       = (HashPage)child;
                        divisor *= pageSize;
                    }
                    else
                    {
                        CollisionItem prev = null;
                        for (CollisionItem item = (CollisionItem)child; item != null; item = item.next)
                        {
                            if (item.hashCode == hashCode && item.key.Equals(key))
                            {
                                if (prev != null)
                                {
                                    prev.next = item.next;
                                    prev.Modify();
                                }
                                else
                                {
                                    pg.items[h] = item.next;
                                    pg.Modify();
                                }
                                nElems -= 1;
                                Modify();
#if USE_GENERICS
                                return(true);
#else
                                return;
#endif
                            }
                            prev = item;
                        }
                        break;
                    }
                }
            }
#if USE_GENERICS
            return(false);
#endif
        }
Пример #4
0
            public void Reset()
            {
                currItem = null;
                nextItem = null;
                stack.Clear();
                HashPage pg = hash.root;

                if (pg != null)
                {
                    int start = 0;
                    int sp    = 0;
DepthFirst:
                    while (true)
                    {
                        for (int i = start; i < pg.items.Count; i++)
                        {
                            object child = pg.items[i];
                            if (child != null)
                            {
                                stack.Add(new StackElem(pg, i));
                                sp += 1;
                                if (child is HashPage)
                                {
                                    pg    = (HashPage)child;
                                    start = 0;
                                    goto DepthFirst;
                                }
                                else
                                {
                                    nextItem = (CollisionItem)child;
                                    return;
                                }
                            }
                        }
                        if (sp != 0)
                        {
                            StackElem top = (StackElem)stack[--sp];
                            stack.RemoveAt(sp);
                            pg    = top.page;
                            start = top.pos + 1;
                        }
                        else
                        {
                            break;
                        }
                    }
                }
            }
Пример #5
0
            public bool MoveNext()
            {
                if (nextItem != null)
                {
                    currItem = nextItem;
                    if ((nextItem = nextItem.next) == null)
                    {
                        int sp = stack.Count;
                        do
                        {
                            StackElem top = (StackElem)stack[--sp];
                            stack.RemoveAt(sp);
                            HashPage pg    = top.page;
                            int      start = top.pos + 1;

DepthFirst:
                            while (true)
                            {
                                for (int i = start; i < pg.items.Count; i++)
                                {
                                    object child = pg.items[i];
                                    if (child != null)
                                    {
                                        stack.Add(new StackElem(pg, i));
                                        sp += 1;
                                        if (child is HashPage)
                                        {
                                            pg    = (HashPage)child;
                                            start = 0;
                                            goto DepthFirst;
                                        }
                                        else
                                        {
                                            nextItem = (CollisionItem)child;
                                            return(true);
                                        }
                                    }
                                }
                                break;
                            }
                        } while (sp != 0);
                    }
                    return(true);
                }
                return(false);
            }
Пример #6
0
        public bool TryGetValue(object key, out object val)
#endif
        {
            HashPage pg = root;

            if (pg != null)
            {
                uint divisor  = 1;
                int  hashCode = key.GetHashCode();
                while (true)
                {
                    int    h     = (int)((uint)hashCode / divisor % pageSize);
                    object child = pg.items[h];
                    if (child is HashPage)
                    {
                        pg       = (HashPage)child;
                        divisor *= pageSize;
                    }
                    else
                    {
                        for (CollisionItem item = (CollisionItem)child; item != null; item = item.next)
                        {
                            if (item.hashCode == hashCode && item.key.Equals(key))
                            {
#if USE_GENERICS
                                val = (V)item.obj;
#else
                                val = item.obj;
#endif
                                return(true);
                            }
                        }
                        break;
                    }
                }
            }
            val = null;
            return(false);
        }
Пример #7
0
 internal StackElem(HashPage page, int pos)
 {
     this.page = page;
     this.pos  = pos;
 }
Пример #8
0
        public void Set(object key, object obj)
        {
            int      hashCode = key.GetHashCode();
            HashPage pg       = root;

            if (pg == null)
            {
                pg = new HashPage(Storage, pageSize);
                int h = (int)((uint)hashCode % pageSize);
                pg.items[h] = new CollisionItem(key, obj, hashCode);
                root        = pg;
                nElems      = 1;
                Modify();
            }
            else
            {
                uint divisor = 1;
                while (true)
                {
                    int    h     = (int)((uint)hashCode / divisor % pageSize);
                    object child = pg.items[h];
                    if (child is HashPage)
                    {
                        pg       = (HashPage)child;
                        divisor *= pageSize;
                    }
                    else
                    {
                        CollisionItem prev = null;
                        CollisionItem last = null;
                        int           collisionChainLength = 0;
                        for (CollisionItem item = (CollisionItem)child; item != null; item = item.next)
                        {
                            if (item.hashCode == hashCode)
                            {
                                if (item.key.Equals(key))
                                {
                                    item.obj = obj;
                                    item.Modify();
                                    return;
                                }
                                if (prev == null || prev.hashCode != hashCode)
                                {
                                    collisionChainLength += 1;
                                }
                                prev = item;
                            }
                            else
                            {
                                collisionChainLength += 1;
                            }
                            last = item;
                        }
                        if (prev == null || prev.hashCode != hashCode)
                        {
                            collisionChainLength += 1;
                        }
                        if (collisionChainLength > loadFactor)
                        {
                            HashPage newPage = new HashPage(Storage, pageSize);
                            divisor *= pageSize;
                            CollisionItem next;
                            for (CollisionItem item = (CollisionItem)child; item != null; item = next)
                            {
                                next = item.next;
                                int hc = (int)((uint)item.hashCode / divisor % pageSize);
                                item.next         = (CollisionItem)newPage.items[hc];
                                newPage.items[hc] = item;
                                item.Modify();
                            }
                            pg.items[h] = newPage;
                            pg.Modify();
                            pg = newPage;
                        }
                        else
                        {
                            CollisionItem newItem = new CollisionItem(key, obj, hashCode);
                            if (prev == null)
                            {
                                prev = last;
                            }
                            if (prev != null)
                            {
                                newItem.next = prev.next;
                                prev.next    = newItem;
                                prev.Modify();
                            }
                            else
                            {
                                pg.items[h] = newItem;
                                pg.Modify();
                            }
                            nElems += 1;
                            Modify();
                            return;
                        }
                    }
                }
            }
        }