mt_put(mrb_state *mrb, mt_tbl *t, mrb_sym sym, size_t func_p, size_t noarg_p, union mt_ptr ptr)
{
  size_t hash, pos, start;
  struct mt_elem *dslot = NULL;

  if (t->alloc == 0) {
    mt_rehash(mrb, t);
  }
  hash = kh_int_hash_func(mrb, sym);
  start = pos = hash & (t->alloc-1);
  for (;;) {
    struct mt_elem *slot = &t->table[pos];

    if (slot->key == sym) {
      slot->func_p = func_p;
      slot->noarg_p = noarg_p;
      slot->ptr = ptr;
      return slot;
    }
    else if (slot->key == 0) {  /* empty or deleted */
      if (slot->func_p == 0) {  /* empty */
        t->size++;
        slot->key = sym;
        slot->func_p = func_p;
        slot->noarg_p = noarg_p;
        slot->ptr = ptr;
        return slot;
      }
      else if (!dslot) {        /* deleted */
        dslot = slot;
      }
    }
    pos = (pos+1) & (t->alloc-1);
    if (pos == start) {         /* not found */
      if (dslot) {
        t->size++;
        dslot->key = sym;
        dslot->func_p = func_p;
        dslot->noarg_p = noarg_p;
        dslot->ptr = ptr;
        return dslot;
      }
      /* no room */
      mt_rehash(mrb, t);
      start = pos = hash & (t->alloc-1);
    }
  }
}
mt_put(mrb_state *mrb, mt_tbl *t, mrb_sym sym, size_t func_p, size_t noarg_p, union mt_ptr ptr)
{
  size_t hash, pos, start;
  struct mt_elem *dslot = NULL;

  if (t->alloc == 0) {
    mt_rehash(mrb, t);
  }
  hash = kh_int_hash_func(mrb, sym);
  start = pos = hash & (t->alloc-1);
  for (;;) {
    struct mt_elem *slot = &t->table[pos];

    if (slot->key == sym) {
      slot->func_p = func_p;
      slot->noarg_p = noarg_p;
      slot->ptr = ptr;
      return slot;
    }
    else if (slot->key == 0) {   
      if (slot->func_p == 0) {   
        t->size++;
        slot->key = sym;
        slot->func_p = func_p;
        slot->noarg_p = noarg_p;
        slot->ptr = ptr;
        return slot;
      }
      else if (!dslot) {         
        dslot = slot;
      }
    }
    pos = (pos+1) & (t->alloc-1);
    if (pos == start) {          
      if (dslot) {
        t->size++;
        dslot->key = sym;
        dslot->func_p = func_p;
        dslot->noarg_p = noarg_p;
        dslot->ptr = ptr;
        return dslot;
      }
       
      mt_rehash(mrb, t);
      start = pos = hash & (t->alloc-1);
    }
  }
}