📄 erl_db.c
字号:
!ONLY_WRITER(p,tb)) { /* We did trap, but no more... */ unfix_table_locked(p, tb); } /* Otherwise keep it fixed */ ERTS_BIF_PREP_RET(result, ret); break; case DB_ERROR_SYSRES: if(IS_HASH_TABLE(tb->common.status) && !ONLY_WRITER(p,tb)) { unfix_table_locked(p, tb); } ERTS_BIF_PREP_ERROR(result, p, SYSTEM_LIMIT); break; default: if(IS_HASH_TABLE(tb->common.status) && !ONLY_WRITER(p,tb)) { unfix_table_locked(p, tb); } ERTS_BIF_PREP_ERROR(result, p, BADARG); break; } db_unlock(tb, LCK_WRITE); erts_match_set_release_result(p); return result;}BIF_RETTYPE ets_select_1(BIF_ALIST_1){ BIF_RETTYPE result; DbTable* tb; int cret; Eterm ret; Eterm *tptr; CHECK_TABLES(); /* * Make sure that the table exists. */ if (!is_tuple(BIF_ARG_1)) { if (BIF_ARG_1 == am_EOT) { BIF_RET(am_EOT); } BIF_ERROR(BIF_P, BADARG); } tptr = tuple_val(BIF_ARG_1); if (arityval(*tptr) < 1 || (tb = db_get_table(BIF_P, tptr[1], DB_READ, LCK_WRITE)) == NULL) { BIF_ERROR(BIF_P, BADARG); } cret = tb->common.meth->db_select_continue(BIF_P,tb, BIF_ARG_1, &ret); switch (cret) { case DB_ERROR_NONE: if(IS_HASH_TABLE(tb->common.status) && DID_TRAP(BIF_P,ret) && !ONLY_WRITER(BIF_P,tb)) { /* We will trap and as we're here this call wasn't a trap... */ fix_table_locked(BIF_P, tb); } /* Otherwise keep it as is */ ERTS_BIF_PREP_RET(result, ret); break; case DB_ERROR_SYSRES: ERTS_BIF_PREP_ERROR(result, BIF_P, SYSTEM_LIMIT); break; default: ERTS_BIF_PREP_ERROR(result, BIF_P, BADARG); break; } db_unlock(tb, LCK_WRITE); erts_match_set_release_result(BIF_P); return result;}BIF_RETTYPE ets_select_2(BIF_ALIST_2){ BIF_RETTYPE result; DbTable* tb; int cret; Eterm ret; CHECK_TABLES(); /* * Make sure that the table exists. */ if ((tb = db_get_table(BIF_P, BIF_ARG_1, DB_READ, LCK_WRITE)) == NULL) { BIF_ERROR(BIF_P, BADARG); } cret = tb->common.meth->db_select(BIF_P, tb, BIF_ARG_2, 0, &ret); /* SMP fixme table may be deleted !!! */ switch (cret) { case DB_ERROR_NONE: if(IS_HASH_TABLE(tb->common.status) && DID_TRAP(BIF_P,ret) && !ONLY_WRITER(BIF_P,tb)) { /* We will trap and as we're here this call wasn't a trap... */ fix_table_locked(BIF_P, tb); } /* Otherwise keep it as is */ ERTS_BIF_PREP_RET(result, ret); break; case DB_ERROR_SYSRES: ERTS_BIF_PREP_ERROR(result, BIF_P, SYSTEM_LIMIT); break; default: ERTS_BIF_PREP_ERROR(result, BIF_P, BADARG); break; } db_unlock(tb, LCK_WRITE); erts_match_set_release_result(BIF_P); return result;}/* We get here instead of in the real BIF when trapping */static BIF_RETTYPE ets_select_count_1(Process *p, Eterm a1){ BIF_RETTYPE result; DbTable* tb; int cret; Eterm ret; Eterm *tptr; CHECK_TABLES(); tptr = tuple_val(a1); ASSERT(arityval(*tptr) >= 1) if ((tb = db_get_table(p, tptr[1], DB_READ, LCK_WRITE)) == NULL) { BIF_ERROR(p, BADARG); } cret = tb->common.meth->db_select_count_continue(p, tb, a1, &ret); switch (cret) { case DB_ERROR_NONE: if(IS_HASH_TABLE(tb->common.status) && !DID_TRAP(p,ret) && !ONLY_WRITER(p,tb)) { /* We did trap, but no more... */ unfix_table_locked(p, tb); } /* Otherwise keep it fixed */ ERTS_BIF_PREP_RET(result, ret); break; case DB_ERROR_SYSRES: if(IS_HASH_TABLE(tb->common.status) && !ONLY_WRITER(p,tb)) { unfix_table_locked(p, tb); } ERTS_BIF_PREP_ERROR(result, p, SYSTEM_LIMIT); break; default: if(IS_HASH_TABLE(tb->common.status) && !ONLY_WRITER(p,tb)) { unfix_table_locked(p, tb); } ERTS_BIF_PREP_ERROR(result, p, BADARG); break; } db_unlock(tb, LCK_WRITE); erts_match_set_release_result(p); return result;}BIF_RETTYPE ets_select_count_2(BIF_ALIST_2){ BIF_RETTYPE result; DbTable* tb; int cret; Eterm ret; CHECK_TABLES(); /* * Make sure that the table exists. */ if ((tb = db_get_table(BIF_P, BIF_ARG_1, DB_READ, LCK_WRITE)) == NULL) { BIF_ERROR(BIF_P, BADARG); } cret = tb->common.meth->db_select_count(BIF_P,tb,BIF_ARG_2, &ret); switch (cret) { case DB_ERROR_NONE: if(IS_HASH_TABLE(tb->common.status) && DID_TRAP(BIF_P,ret) && !ONLY_WRITER(BIF_P,tb)) { /* We will trap and as we're here this call wasn't a trap... */ fix_table_locked(BIF_P, tb); } /* Otherwise keep it as is */ ERTS_BIF_PREP_RET(result, ret); break; case DB_ERROR_SYSRES: ERTS_BIF_PREP_ERROR(result, BIF_P, SYSTEM_LIMIT); break; default: ERTS_BIF_PREP_ERROR(result, BIF_P, BADARG); break; } db_unlock(tb, LCK_WRITE); erts_match_set_release_result(BIF_P); return result;}BIF_RETTYPE ets_select_reverse_3(BIF_ALIST_3){ BIF_RETTYPE result; DbTable* tb; int cret; Eterm ret; Sint chunk_size; CHECK_TABLES(); /* * Make sure that the table exists. */ if ((tb = db_get_table(BIF_P, BIF_ARG_1, DB_READ, LCK_WRITE)) == NULL) { BIF_ERROR(BIF_P, BADARG); } /* Chunk size strictly greater than 0 */ if (is_not_small(BIF_ARG_3) || (chunk_size = signed_val(BIF_ARG_3)) <= 0) { db_unlock(tb, LCK_WRITE); BIF_ERROR(BIF_P, BADARG); } cret = tb->common.meth->db_select_chunk(BIF_P,tb, BIF_ARG_2, chunk_size, 1 /* reversed */, &ret); switch (cret) { case DB_ERROR_NONE: if(IS_HASH_TABLE(tb->common.status) && DID_TRAP(BIF_P,ret) && !ONLY_WRITER(BIF_P,tb)) { /* We will trap and as we're here this call wasn't a trap... */ fix_table_locked(BIF_P, tb); } /* Otherwise keep it as is */ ERTS_BIF_PREP_RET(result, ret); break; case DB_ERROR_SYSRES: ERTS_BIF_PREP_ERROR(result, BIF_P, SYSTEM_LIMIT); break; default: ERTS_BIF_PREP_ERROR(result, BIF_P, BADARG); break; } db_unlock(tb, LCK_WRITE); erts_match_set_release_result(BIF_P); return result;}BIF_RETTYPE ets_select_reverse_1(BIF_ALIST_1){ return ets_select_1(BIF_P, BIF_ARG_1);}BIF_RETTYPE ets_select_reverse_2(BIF_ALIST_2){ BIF_RETTYPE result; DbTable* tb; int cret; Eterm ret; CHECK_TABLES(); /* * Make sure that the table exists. */ if ((tb = db_get_table(BIF_P, BIF_ARG_1, DB_READ, LCK_WRITE)) == NULL) { BIF_ERROR(BIF_P, BADARG); } cret = tb->common.meth->db_select(BIF_P,tb,BIF_ARG_2, 1 /*reversed*/, &ret); switch (cret) { case DB_ERROR_NONE: if(IS_HASH_TABLE(tb->common.status) && DID_TRAP(BIF_P,ret) && !ONLY_WRITER(BIF_P,tb)) { /* We will trap and as we're here this call wasn't a trap... */ fix_table_locked(BIF_P, tb); } /* Otherwise keep it as is */ ERTS_BIF_PREP_RET(result, ret); break; case DB_ERROR_SYSRES: ERTS_BIF_PREP_ERROR(result, BIF_P, SYSTEM_LIMIT); break; default: ERTS_BIF_PREP_ERROR(result, BIF_P, BADARG); break; } db_unlock(tb, LCK_WRITE); erts_match_set_release_result(BIF_P); return result;}/* ** ets:match_object(Continuation), ets:match_object(Table, Pattern), ets:match_object(Table,Pattern,ChunkSize) */BIF_RETTYPE ets_match_object_1(BIF_ALIST_1){ return ets_select_1(BIF_P, BIF_ARG_1);}BIF_RETTYPE ets_match_object_2(BIF_ALIST_2){ Eterm ms; Eterm buff[8]; Eterm *hp = buff; /*hp = HAlloc(BIF_P, 8);*/ ms = CONS(hp, am_DollarUnderscore, NIL); hp += 2; ms = TUPLE3(hp, BIF_ARG_2, NIL, ms); hp += 4; ms = CONS(hp, ms, NIL); return ets_select_2(BIF_P, BIF_ARG_1, ms);}BIF_RETTYPE ets_match_object_3(BIF_ALIST_3){ Eterm ms; Eterm buff[8]; Eterm *hp = buff; /*hp = HAlloc(BIF_P, 8);*/ ms = CONS(hp, am_DollarUnderscore, NIL); hp += 2; ms = TUPLE3(hp, BIF_ARG_2, NIL, ms); hp += 4; ms = CONS(hp, ms, NIL); return ets_select_3(BIF_P, BIF_ARG_1, ms, BIF_ARG_3);}/* ** BIF to extract information about a particular table** Only the "memory" parameter generates table specific calls.*/ BIF_RETTYPE ets_db_info_2(BIF_ALIST_2){ DbTable* tb; Eterm ret = THE_NON_VALUE; if ((tb = db_get_table(BIF_P, BIF_ARG_1, DB_INFO, LCK_READ)) == NULL) { BIF_ERROR(BIF_P, BADARG); } if (BIF_ARG_2 == am_size) ret = make_small(tb->common.nitems); else if (BIF_ARG_2 == am_type) { if (tb->common.status & DB_SET) { ret = am_set; } else if (tb->common.status & DB_DUPLICATE_BAG) { ret = am_duplicate_bag; } else if (tb->common.status & DB_ORDERED_SET) { ret = am_ordered_set; } /*TT*/ else { ret = am_bag; } } else if (BIF_ARG_2 == am_memory) { Uint words = (Uint) ((erts_smp_atomic_read(&tb->common.memory_size) + sizeof(Uint) - 1) / sizeof(Uint)); ret = erts_make_integer(words, BIF_P); } else if (BIF_ARG_2 == am_owner) ret = tb->common.owner; else if (BIF_ARG_2 == am_protection) { if (tb->common.status & DB_PRIVATE) ret = am_private; else if (tb->common.status & DB_PROTECTED) ret = am_protected; else if (tb->common.status & DB_PUBLIC) ret = am_public; } else if (BIF_ARG_2 == am_name) ret = tb->common.the_name; else if (BIF_ARG_2 == am_keypos) ret = make_small(tb->common.keypos); /* For debugging purpouses */ else if (BIF_ARG_2 == am_data) { print_table(ERTS_PRINT_STDOUT, NULL, 1, tb); ret = am_true; } else if (BIF_ARG_2 == am_atom_put("fixed",5)) { if (tb->common.status & DB_FIXED) ret = am_true; else ret = am_false; } else if (BIF_ARG_2 == am_atom_put("kept_objects",12)) ret = make_small(tb->common.kept_items); else if (BIF_ARG_2 == am_atom_put("safe_fixed",10)) { if (tb->common.fixations != NULL) { Uint need; Eterm *hp; Eterm tpl, lst; DbFixation *fix; need = 7; for (fix = tb->common.fixations; fix != NULL; fix = fix->next) { need += 5; } hp = HAlloc(BIF_P,need); lst = NIL; for (fix = tb->common.fixations; fix != NULL; fix = fix->next) { tpl = TUPLE2(hp,fix->pid,make_small(fix->counter)); hp += 3; lst = CONS(hp,tpl,lst); hp += 2; } tpl = TUPLE3(hp, make_small(tb->common.megasec), make_small(tb->common.sec), make_small(tb->common.microsec)); hp += 4; ret = TUPLE2(hp, tpl, lst); } else { ret = am_false; } } db_unlock(tb, LCK_READ); if (ret == THE_NON_VALUE) BIF_ERROR(BIF_P, BADARG); BIF_RET(ret);}BIF_RETTYPE ets_is_compiled_ms_1(BIF_ALIST_1){ if (erts_db_is_compiled_ms(BIF_ARG_1)) { BIF_RET(am_true); } else { BIF_RET(am_false); }}BIF_RETTYPE ets_match_spec_compile_1(BIF_ALIST_1){ Binary *mp = db_match_set_compile(BIF_P, BIF_ARG_1, DCOMP_TABLE); ProcBin *pb; if (mp == NULL) { BIF_ERROR(BIF_P, BADARG); } erts_refc_inc(&mp->refc, 1); pb = (ProcBin *) HAlloc(BIF_P, PROC_BIN_SIZE); pb->thing_word = HEADER_PROC_BIN; pb->size = 0; pb->next = MSO(BIF_P).mso; MSO(BIF_P).mso = pb; pb->val = mp; pb->bytes = (byte*) mp->orig_bytes; BIF_RET(make_binary(pb));}BIF_RETTYPE ets_match_spec_run_r_3(BIF_ALIST_3){ Eterm ret = BIF_ARG_3; int i = 0; Eterm *hp; Eterm lst; ProcBin *bp; Binary *mp; Eterm res; Uint32 dummy; Uint sz; if (!(is_list(BIF_ARG_1) || BIF_ARG_1 == NIL) || !is_binary(BIF_ARG_2)) { error: BIF_ERROR(BIF_P, BADARG); } bp = (ProcBin*) binary_val(BIF_ARG_2); if (thing_subtag(bp->thing_word) != REFC_BINARY_SUBTAG) { goto error; } mp = bp->val; if (!(mp->flags & BIN_FLAG_MATCH_PROG)) { goto error; } if (BIF_ARG_1 == NIL) { BIF_RET(BIF_ARG_3); } for (lst = BIF_ARG_1; is_list(lst); lst = CDR(list_val(lst))) { if (++i > CONTEXT_REDS) { BUMP_ALL_REDS(BIF_P); BIF_TRAP3(bif_export[BIF_ets_match_spec_run_r_3], BIF_P,lst,BIF_ARG_2,ret); } res = db_prog_match(BIF_P, mp, CAR(list_val(lst)), 0, &dummy); if (is_value(res)) { sz = size_object(res); hp = HAlloc(BIF_P, sz + 2); res = copy_struct(res, sz, &hp, &MSO(BIF_P)); ret = CONS(hp,res,ret); /*hp += 2;*/ }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -