static HashElem FindElementGivenHash(Hash hash, string key, int keyLength, uint h) { HashElem elem; // Used to loop thru the element list int count; // Number of elements left to test if (hash.Table != null && hash.Table[h] != null) { HTable entry = hash.Table[h]; elem = entry.Chain; count = entry.Count; } else { elem = hash.First; count = (int)hash.Count; } while (count-- > 0 && C._ALWAYS(elem != null)) { if (elem.KeyLength == keyLength && elem.Key.Equals(key, StringComparison.OrdinalIgnoreCase)) { return(elem); } elem = elem.Next; } return(null); }
static bool Rehash(Hash hash, uint newSize) { #if MALLOC_SOFT_LIMIT if (newSize * sizeof(HTable) > MALLOC_SOFT_LIMIT) { newSize = MALLOC_SOFT_LIMIT / sizeof(HTable); } if (newSize == hash.TableSize) { return(false); } #endif // The inability to allocates space for a larger hash table is a performance hit but it is not a fatal error. So mark the // allocation as a benign. Use sqlite3Malloc()/memset(0) instead of sqlite3MallocZero() to make the allocation, as sqlite3MallocZero() // only zeroes the requested number of bytes whereas this module will use the actual amount of space allocated for the hash table (which // may be larger than the requested amount). C._benignalloc_begin(); HTable[] newTable = new HTable[newSize]; // The new hash table for (int i = 0; i < newSize; i++) { newTable[i] = new HTable(); } C._benignalloc_end(); if (newTable == null) { return(false); } C._free(ref hash.Table); hash.Table = newTable; //hash.TableSize = newSize = SysEx.AllocSize(newTable) / sizeof(HTable); hash.TableSize = newSize; HashElem elem, nextElem; for (elem = hash.First, hash.First = null; elem != null; elem = nextElem) { uint h = GetHashCode(elem.Key, elem.KeyLength) % newSize; nextElem = elem.Next; InsertElement(hash, newTable[h], elem); } return(true); }
static void InsertElement(Hash hash, HTable entry, HashElem newElem) { HashElem headElem; // First element already in entry if (entry != null) { headElem = (entry.Count != 0 ? entry.Chain : null); entry.Count++; entry.Chain = newElem; } else { headElem = null; } if (headElem != null) { newElem.Next = headElem; newElem.Prev = headElem.Prev; if (headElem.Prev != null) { headElem.Prev.Next = newElem; } else { hash.First = newElem; } headElem.Prev = newElem; } else { newElem.Next = hash.First; if (hash.First != null) { hash.First.Prev = newElem; } newElem.Prev = null; hash.First = newElem; } }