mt_get(mrb_state *mrb, mt_tbl *t, mrb_sym sym, union mt_ptr *pp)
{
  int hash, pos, start;

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

  mrb_sym *keys = (mrb_sym*)&t->ptr[t->alloc];
  union mt_ptr *vals = t->ptr;
  hash = kh_int_hash_func(mrb, sym);
#ifdef MRB_USE_INLINE_METHOD_CACHE
  int 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 (;;) {
    mrb_sym key = keys[pos];
    if (MT_KEY_SYM(key) == sym) {
      *pp = vals[pos];
#ifdef MRB_USE_INLINE_METHOD_CACHE
      if (pos < 0xff) {
        mt_cache[cpos] = pos;
      }
#endif
      return key;
    }
    else if (key == MT_EMPTY) {
      return 0;
    }
    pos = (pos+1) & (t->alloc-1);
    if (pos == start) {         /* not found */
      return 0;
    }
  }
}
mt_get(mrb_state *mrb, mt_tbl *t, mrb_sym sym, union mt_ptr *pp)
{
  int hash, pos, start;

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

  mrb_sym *keys = (mrb_sym*)&t->ptr[t->alloc];
  union mt_ptr *vals = t->ptr;
  hash = kh_int_hash_func(mrb, sym);
#ifdef MRB_USE_INLINE_METHOD_CACHE
  int 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 (;;) {
    mrb_sym key = keys[pos];
    if (MT_KEY_SYM(key) == sym) {
      *pp = vals[pos];
#ifdef MRB_USE_INLINE_METHOD_CACHE
      if (pos < 0xff) {
        mt_cache[cpos] = pos;
      }
#endif
      return key;
    }
    else if (key == MT_EMPTY) {
      return 0;
    }
    pos = (pos+1) & (t->alloc-1);
    if (pos == start) {          
      return 0;
    }
  }
}