Exemple #1
0
        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);
        }
Exemple #2
0
        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);
        }
Exemple #3
0
        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;
            }
        }