Beispiel #1
0
static void
rob_from_rich (scm_t_weak_set *set, unsigned long k)
{
  unsigned long empty, size;

  size = set->size;

  /* If we are to free up slot K in the set, we need room to do so.  */
  assert (set->n_items < size);
  
  empty = k;
  do 
    empty = (empty + 1) % size;
  /* Here we access key outside the lock.  Is this a problem?  At first
     glance, I wouldn't think so.  */
  while (set->entries[empty].key);

  do
    {
      unsigned long last = empty ? (empty - 1) : (size - 1);
      move_weak_entry (&set->entries[last], &set->entries[empty]);
      empty = last;
    }
  while (empty != k);

  /* Just for sanity.  */
  set->entries[empty].hash = 0;
  set->entries[empty].key = 0;
}
Beispiel #2
0
static void
rob_from_rich (scm_t_weak_table *table, unsigned long k)
{
  unsigned long empty, size;

  size = table->size;

  /* If we are to free up slot K in the table, we need room to do so.  */
  assert (table->n_items < size);
  
  empty = k;
  do 
    empty = (empty + 1) % size;
  while (table->entries[empty].hash);

  do
    {
      unsigned long last = empty ? (empty - 1) : (size - 1);
      move_weak_entry (&table->entries[last], &table->entries[empty],
                       table->kind);
      empty = last;
    }
  while (empty != k);

  table->entries[empty].hash = 0;
  table->entries[empty].key = 0;
  table->entries[empty].value = 0;
}
Beispiel #3
0
static void
give_to_poor (scm_t_weak_table *table, unsigned long k)
{
  /* Slot K was just freed up; possibly shuffle others down.  */
  unsigned long size = table->size;

  while (1)
    {
      unsigned long next = (k + 1) % size;
      unsigned long hash;
      scm_t_weak_entry copy;

      hash = table->entries[next].hash;

      if (!hash || hash_to_index (hash, size) == next)
        break;

      copy_weak_entry (&table->entries[next], &copy);

      if (!copy.key || !copy.value)
        /* Lost weak reference.  */
        {
          give_to_poor (table, next);
          table->n_items--;
          continue;
        }

      move_weak_entry (&table->entries[next], &table->entries[k],
                       table->kind);

      k = next;
    }

  /* We have shuffled down any entries that should be shuffled down; now
     free the end.  */
  table->entries[k].hash = 0;
  table->entries[k].key = 0;
  table->entries[k].value = 0;
}