mt_get(mrb_state *mrb, mt_tbl *t, mrb_sym sym)
{
  size_t hash, pos, start;

  if (t == NULL) return NULL;
  if (t->alloc == 0) return NULL;
  if (t->size == 0) return NULL;

  hash = kh_int_hash_func(mrb, sym);
#ifdef MRB_USE_INLINE_METHOD_CACHE
  size_t cpos = (hash^(uintptr_t)t) % MT_CACHE_SIZE;
  pos = mt_cache[cpos];
  if (cpos < t->alloc && t->table[cpos].key == sym) {
    return &t->table[cpos];
  }
#endif
  start = pos = hash & (t->alloc-1);
  for (;;) {
    struct mt_elem *slot = &t->table[pos];

    if (slot->key == sym) {
#ifdef MRB_USE_INLINE_METHOD_CACHE
      if (pos < 0xff) {
        mt_cache[cpos] = pos;
      }
#endif
      return slot;
    }
    else if (slot_empty_p(slot)) {
      return NULL;
    }
    pos = (pos+1) & (t->alloc-1);
    if (pos == start) {         /* not found */
      return NULL;
    }
  }
}
mt_get(mrb_state *mrb, mt_tbl *t, mrb_sym sym)
{
  size_t hash, pos, start;

  if (t == NULL) return NULL;
  if (t->alloc == 0) return NULL;
  if (t->size == 0) return NULL;

  hash = kh_int_hash_func(mrb, sym);
#ifdef MRB_USE_INLINE_METHOD_CACHE
  size_t cpos = (hash^(uintptr_t)t) % MT_CACHE_SIZE;
  pos = mt_cache[cpos];
  if (cpos < t->alloc && t->table[cpos].key == sym) {
    return &t->table[cpos];
  }
#endif
  start = pos = hash & (t->alloc-1);
  for (;;) {
    struct mt_elem *slot = &t->table[pos];

    if (slot->key == sym) {
#ifdef MRB_USE_INLINE_METHOD_CACHE
      if (pos < 0xff) {
        mt_cache[cpos] = pos;
      }
#endif
      return slot;
    }
    else if (slot_empty_p(slot)) {
      return NULL;
    }
    pos = (pos+1) & (t->alloc-1);
    if (pos == start) {          
      return NULL;
    }
  }
}