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); }
public override void Clear() #endif { if (root != null) { root.Deallocate(); root = null; nElems = 0; Modify(); } }
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 }
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; } } } }
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); }
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); }
internal StackElem(HashPage page, int pos) { this.page = page; this.pos = pos; }
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; } } } } }