예제 #1
0
        public static ObjString tableFindString(ref Table_t table, char[] chars, int _start, int length, uint hash)
        {
            if (table.count == 0)
            {
                return(null);
            }

            uint index = (uint)(hash & table.capacity);

            for (;;)
            {
                Entry entry = table.entries[index];

                if (entry.key == null)
                {
                    // Stop if we find an empty non-tombstone entry.
                    if (Value.IS_NIL(entry.value))
                    {
                        return(null);
                    }
                }
                else if (entry.key.length == length &&
                         entry.key.hash == hash &&
                         Cfun._memcmp(entry.key.chars, entry.key._start, chars, _start, length))
                {
                    // We found it.
                    return(entry.key);
                }


                index = (uint)((index + 1) & table.capacity);
            }
        }
예제 #2
0
        public static bool tableSet(ref Table_t table, ObjString key, Value_t value)
        {
            if (table.count + 1 > (table.capacity + 1) * TABLE_MAX_LOAD)
            {
                int capacity = Memory.GROW_CAPACITY(table.capacity + 1) - 1;
                adjustCapacity(ref table, capacity);
            }

            int   _index = -1; // work around
            Entry entry  = findEntry(ref table.entries, table.capacity, key, ref _index);

            bool isNewKey = entry.key == null;

            if (isNewKey && Value.IS_NIL(entry.value))
            {
                table.count++;
            }

            entry.key   = key;
            entry.value = value;

            table.entries[_index] = entry; // CS workaround

            return(isNewKey);
        }
예제 #3
0
 public static void markTable(ref Table_t table)
 {
     for (int i = 0; i <= table.capacity; i++)
     {
         Entry entry = table.entries[i];
         Memory.markObject((Obj)entry.key);
         Memory.markValue(ref entry.value);
     }
 }
예제 #4
0
 public static void tableRemoveWhite(ref Table_t table)
 {
     for (int i = 0; i <= table.capacity; i++)
     {
         Entry entry = table.entries[i];
         if (entry.key != null && !entry.key.isMarked) // clox: entry->key->obj.isMarked
         {
             tableDelete(ref table, entry.key);
         }
     }
 }
예제 #5
0
 public static void tableAddAll(ref Table_t from, ref Table_t to)
 {
     for (int i = 0; i <= from.capacity; i++)
     {
         Entry entry = from.entries[i];
         if (entry.key != null)
         {
             tableSet(ref to, entry.key, entry.value);
         }
     }
 }
예제 #6
0
        public static bool tableGet(ref Table_t table, ObjString key, ref Value_t value)
        {
            if (table.count == 0)
            {
                return(false);
            }
            int   _index = -1; // work around
            Entry entry  = findEntry(ref table.entries, table.capacity, key, ref _index);

            if (entry.key == null)
            {
                return(false);
            }

            value = entry.value;
            return(true);
        }
예제 #7
0
        private static void adjustCapacity(ref Table_t table, int capacity)
        {
            Entry[] entries = Memory.ALLOCATE <Entry>(capacity + 1);

            //fix
            for (int i = 0; i < entries.Length; i++)
            {
                entries[i] = new Entry();
            }

            for (int i = 0; i <= capacity; i++)
            {
                entries[i].key   = null;
                entries[i].value = Value.NIL_VAL();
            }

            table.count = 0;

            for (int i = 0; i <= table.capacity; i++)
            {
                Entry entry = table.entries[i];
                if (entry.key == null)
                {
                    continue;
                }

                int   _index = -1; // work around
                Entry dest   = findEntry(ref entries, capacity, entry.key, ref _index);
                dest.key   = entry.key;
                dest.value = entry.value;

                entries[_index] = dest; // CS workaround

                table.count++;
            }


            Memory.FREE_ARRAY <Entry>(typeof(Entry), ref table.entries, table.capacity + 1);
            table.entries  = entries;
            table.capacity = capacity;
        }
예제 #8
0
        public static bool tableDelete(ref Table_t table, ObjString key)
        {
            if (table.count == 0)
            {
                return(false);
            }

            // Find the entry.
            int   _index = -1;
            Entry entry  = findEntry(ref table.entries, table.capacity, key, ref _index);

            if (entry.key == null)
            {
                return(false);
            }

            // Place a tombstone in the entry.
            entry.key             = null;
            entry.value           = Value.BOOL_VAL(true);
            table.entries[_index] = entry; // Csharp ref workaround

            return(true);
        }
예제 #9
0
 public static void freeTable(ref Table_t table)
 {
     Memory.FREE_ARRAY <Entry>(typeof(Entry), ref table.entries, table.capacity + 1);
     initTable(ref table);
 }
예제 #10
0
 public static void initTable(ref Table_t table)
 {
     table.count    = 0;
     table.capacity = -1;
     table.entries  = null;
 }