static int new_crab_obj(lua_State *L){ luaL_checktype(L, 1, LUA_TTABLE);//检查第一个参数是否是table Table *dict = (Table*)lua_newuserdata(L, sizeof(Table)); set_crab_obj_flag(L); dict->capacity = 1; dict->node = (TableNode*)malloc(sizeof(TableNode)); initnode(dict->node); dict->lastfree = dict->node; size_t len = lua_rawlen(L, 1); size_t i; for(i=1;i<=len;i++) { lua_rawgeti(L, 1, i); if(!_dict_insert(L, dict)) { _disct_free(dict); return luaL_error(L, "illegal parameters in table index %d", i); } lua_pop(L, 1); } //_dict_dump(dict, 0); // don't close old g_dict, avoid crash return 1; }
bool BX_Dict_Insert(struct BX_Dict *dict, struct BoolExpr *key, struct BoolExpr *val) { double load; if (!_dict_insert(dict, key, val)) return false; // LCOV_EXCL_LINE load = (double) dict->length / (double) _primes[dict->_pridx]; if (dict->_pridx < MAX_IDX && load > MAX_LOAD) { if (!_enlarge(dict)) return false; // LCOV_EXCL_LINE } return true; }
static int dict_open(lua_State *L) { luaL_checktype(L, 1, LUA_TTABLE); Table *dict = table_new(); size_t len = lua_rawlen(L,1); size_t i; for(i=1;i<=len;i++) { lua_rawgeti(L, 1, i); if(!_dict_insert(L, dict)) { _dict_close(dict); return luaL_error(L, "illegal parameters in table index %d", i); } lua_pop(L, 1); } g_dict = dict; return 0; }
static bool _enlarge(struct BX_Dict *dict) { struct BX_DictItem *item; size_t pridx = dict->_pridx; size_t length = dict->length; struct BX_DictItem **items = dict->items; size_t old_width = _primes[pridx]; size_t new_width = _primes[pridx + 1]; dict->_pridx += 1; dict->length = 0; dict->items = malloc(new_width * sizeof(struct BX_DictItem *)); if (dict->items == NULL) return false; // LCOV_EXCL_LINE for (size_t i = 0; i < new_width; ++i) dict->items[i] = (struct BX_DictItem *) NULL; for (size_t i = 0; i < old_width; ++i) { for (item = items[i]; item; item = item->tail) { if (!_dict_insert(dict, item->key, item->val)) { /* LCOV_EXCL_START */ for (size_t j = 0; j < i; ++j) _list_del(dict->items[j]); free(dict->items); dict->_pridx = pridx; dict->length = length; dict->items = items; return false; /* LCOV_EXCL_STOP */ } } } for (size_t i = 0; i < old_width; ++i) _list_del(items[i]); free(items); return true; }