123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598 |
- #include <dirent.h>
- #include <rid.h>
- #include <stdint.h>
- #include <stdio.h>
- #include <stdlib.h>
- #define STYLE_9
- #include <fn85.h>
- #include <rid_fn85.h>
- #include <unfy/unfy.h>
- #include <rls/rls.h>
- #include <rls/rlsp.h>
- #define NIT_SHORT_NAMES
- #include <nit/list.h>
- #include <nit/set.h>
- #include <nit/map.h>
- #include <nit/err.h>
- #include <nit/file.h>
- #include <nit/buf.h>
- #include <nit/gap.h>
- #include "utilize.h"
- #include "examine.h"
- #include "front.h"
- #include "config.h"
- /* add_________________ */
- const Rid ilk_add_id = { 0x1f, 0x98, 0x8a, 0xb8, 0xfb, 0xe0, 0x0e, 0x10,
- 0xfb, 0xe0, 0x0e, 0x10, 0xfb, 0xe0, 0x0e, 0x10 };
- /* id__________________ */
- const Rid ilk_id_id = { 0x38, 0x84, 0x13, 0x2b, 0xfb, 0xe0, 0x0e, 0x10,
- 0xfb, 0xe0, 0x0e, 0x10, 0xfb, 0xe0, 0x0e, 0x10 };
- /* head________________ */
- const Rid ilk_head_id = { 0x35, 0x69, 0x1f, 0x92, 0xfb, 0xe0, 0x0e, 0x10,
- 0xfb, 0xe0, 0x0e, 0x10, 0xfb, 0xe0, 0x0e, 0x10 };
- /* Core code */
- static Ilk_grp *
- grp_get(Ilk_sys *sys, const Rid id, Rls_rule *rules)
- {
- Ilk_grp *grp = sys->lib->old_grps;
- if (grp) {
- sys->lib->old_grps = (Ilk_grp *) grp->rules;
- } else if (!(grp = malloc(sizeof(*grp)))) {
- Rid_fn85 str;
- err_std(&sys->lib->err);
- rid_fn85(str, id);
- err_where(&sys->lib->err, str);
- return NULL;
- }
- rid_set(grp->id, id);
- grp->rules = rules;
- grp->changed = 0;
- grp->accessed = 1;
- return grp;
- }
- static void
- grp_recycle(Ilk_sys *sys, Ilk_grp *grp)
- {
- grp->rules = (Rls_rule *) sys->lib->old_grps;
- sys->lib->old_grps = grp;
- }
- Ilk_grp *
- ilk_grp_load(Ilk_sys *sys, const Rid id, Unfy_stat *stat)
- {
- Ilk_rule_path path;
- Ilk_grp *grp = grp_get(sys, id, NULL);
- if (!grp)
- goto err_no_mem;
- ilk_rule_path(path, id);
- switch (file_exists(&sys->dir, path, &sys->lib->err)) {
- case 0:
- if (stat) {
- *stat = UNFY_NO;
- grp_recycle(sys, grp);
- return NULL;
- }
- break;
- case 1:
- if (ilk_path_grp(grp, path, 1, sys) >= 0)
- break;
- /* fallthru */
- default:
- goto err_grp;
- }
- if (map_add(&sys->grps, id, sizeof(Rid), grp, &sys->lib->stack) < 0) {
- err_cust(&sys->lib->err, "Failed to add grp");
- goto err_grp;
- }
- return grp;
- err_grp:
- grp_recycle(sys, grp);
- err_no_mem:
- if (stat)
- *stat = UNFY_ERR;
- return NULL;
- }
- int
- ilk_grp_unload(Ilk_grp *grp, Ilk_sys *sys)
- {
- if (ilk_grp_save(grp, sys) < 0)
- return -1;
- ilk_grp_discard(grp, sys);
- return 0;
- }
- void
- ilk_grp_discard(Ilk_grp *grp, Ilk_sys *sys)
- {
- ilk_grp_dispose(grp, sys);
- map_remove(&sys->grps, grp->id, sizeof(grp->id), &sys->lib->stack);
- grp_recycle(sys, grp);
- }
- Ilk_grp *
- ilk_grp_get(Ilk_sys *sys, const Rid id, Unfy_stat *stat)
- {
- Ilk_grp *grp = map_get(&sys->grps, id, sizeof(Rid));
- if (!grp)
- grp = ilk_grp_load(sys, id, stat);
- if (grp)
- grp->accessed = 1;
- return grp;
- }
- static int
- rule_name(const Unfy_term *term, Rid id)
- {
- if (!term)
- return -1;
- switch (term->type) {
- case UNFY_CONST:
- rid_set(id, term->u.id);
- return 0;
- case UNFY_LIST:
- if (!term->u.list || term->u.list->term->type != UNFY_CONST)
- return -1;
- rid_set(id, term->u.list->term->u.id);
- return 0;
- default:
- break;
- }
- return -1;
- }
- Ilk_grp *
- ilk_grp_get_term(Ilk_sys *sys, const Unfy_term *term, Unfy_stat *stat)
- {
- Rid id;
- if (rule_name(term, id) < 0) {
- if (stat)
- *stat = UNFY_ERR;
- err_cust(&sys->lib->err, "Invalid rule name");
- return NULL;
- }
- return ilk_grp_get(sys, id, stat);
- }
- int
- ilk_grp_save(Ilk_grp *grp, Ilk_sys *sys)
- {
- size_t pos = 0;
- Ilk_rule_path path;
- Nit_file file;
- Nit_err tmp;
- if (!grp->changed)
- return 0;
- ilk_rule_path(path, grp->id);
- if (rlsp_rule_ser(grp->rules, &sys->lib->buf.bytes, &sys->lib->buf.size,
- &pos, &sys->lib->srlz, sys) < 0) {
- err_cust(&sys->lib->err, "Failed to serialize rules");
- goto err_no_file;
- }
- if (dir_sub(&sys->dir, path, &sys->lib->err) < 0 ||
- file_open(&file, &sys->dir, path, &sys->lib->err) < 0)
- goto err_no_file;
- if (file_write(&file, grp->id, sizeof(Rid), &sys->lib->err) < 0 ||
- file_write(&file, sys->lib->buf.bytes, pos, &sys->lib->err) < 0)
- goto err_file;
- file_cutoff(&file);
- if(file_close(&file, &sys->lib->err) < 0)
- goto err_file;
- grp->changed = 0;
- return 0;
- err_file:
- file_close(&file, &tmp);
- err_no_file:
- err_where(&sys->lib->err, path);
- return -1;
- }
- int
- ilk_rule_origin(Rls_rule *rule, Rls_srch **srch_ref,
- uint64_t srch_cnt, Ilk_sys *sys)
- {
- Ilk_srch_path path;
- Rid_fn85 id_str;
- if (rule) {
- Ilk_more *more = rule->dat;
- /* a priori*/
- if (!more->srch_cnt) {
- *srch_ref = NULL;
- return 0;
- }
- if (!*srch_ref &&
- ilk_srch_get(srch_ref, more->srch_cnt, sys) < 0)
- return -1;
- }
- for (; *srch_ref; rls_srch_next(srch_ref)) {
- Unfy_term *id;
- if (!rid_cmp((*srch_ref)->rule->id, ilk_add_id) &&
- (!rule ||
- ((id = unfy_bind_get((*srch_ref)->rbind, ilk_id_id)) &&
- !rid_cmp(id->u.id, rule->id))))
- return 0;
- }
- if (!rule)
- return 0;
- err_cust(&sys->lib->err, "Srch file does not contain rule");
- ilk_srch_path(path, srch_cnt);
- err_where(&sys->lib->err, path);
- rid_fn85(id_str, rule->id);
- err_what(&sys->lib->err, id_str);
- return -1;
- }
- int
- ilk_meta_init(Ilk_meta *meta, uint64_t srch_cnt, uint64_t deps_len)
- {
- meta->srch_cnt = srch_cnt;
- return gap_init(&meta->deps, deps_len);
- }
- void
- ilk_meta_dispose(Ilk_meta *meta)
- {
- gap_dispose(&meta->deps);
- }
- void
- ilk_meta_get(Ilk_meta *meta, Rls_srch **srch_ref, Ilk_sys *sys)
- {
- Unfy_term *id;
- Unfy_term *head;
- ilk_rule_origin(NULL, srch_ref, meta->srch_cnt, sys);
- if (!*srch_ref)
- return;
- id = unfy_bind_get((*srch_ref)->rbind, ilk_id_id);
- rid_set(meta->id, id->u.id);
- head = unfy_bind_get((*srch_ref)->rbind, ilk_head_id);
- rule_name(head, meta->grp_id);
- meta->changed = 1;
- }
- int
- ilk_meta_save(Ilk_sys *sys, Ilk_meta *meta)
- {
- size_t pos = 0;
- size_t size = 0;
- unsigned char *buf = NULL;
- Ilk_meta_path path;
- Nit_file file;
- Nit_err tmp;
- if (!meta->changed)
- return 0;
- ilk_meta_path(path, meta->id);
- if (ilk_meta_ser(meta, &buf, &size, &pos) < 0) {
- err_cust(&sys->lib->err, "Failed to serialize rules");
- goto err_no_file;
- }
- if (dir_sub(&sys->dir, path, &sys->lib->err) < 0 ||
- file_open(&file, &sys->dir, path, &sys->lib->err) < 0)
- goto err_no_file;
- if (file_set(&file, buf, pos, &sys->lib->err) < 0 ||
- file_close(&file, &sys->lib->err) < 0)
- goto err_file;
- free(buf);
- meta->changed = 0;
- return 0;
- err_file:
- file_close(&file, &tmp);
- err_no_file:
- free(buf);
- err_where(&sys->lib->err, path);
- return -1;
- }
- int
- ilk_meta_load(Ilk_meta *meta, const Rid id, Ilk_sys *sys)
- {
- Ilk_rule_path path;
- ilk_meta_path(path, id);
- rid_set(meta->id, id);
- return ilk_path_meta(meta, path, 1, sys);
- }
- int
- ilk_meta_dep(Ilk_meta *meta, uint64_t srch_cnt)
- {
- gap_end(&meta->deps);
- return gap_write(&meta->deps, &srch_cnt, sizeof(srch_cnt));
- }
- static void
- clean_grps(Ilk_sys *sys)
- {
- Nit_iter iter;
- int more = 1;
- if (!sys->grps.entry_num)
- return;
- iter_init(&iter, &sys->grps);
- while (more) {
- Ilk_grp *grp = iter_val(&iter);
- more = iter_next(&iter);
- if (grp->accessed) {
- grp->accessed = 0;
- continue;
- }
- /* If we can't unload, it's no big deal. We'll do it later. */
- ilk_grp_unload(grp, sys);
- }
- }
- static void
- clean_srchs(Ilk_sys *sys)
- {
- Nit_iter iter;
- int more = 1;
- if (!sys->srchs.entry_num)
- return;
- iter_init(&iter, &sys->srchs);
- while (more) {
- Ilk_grp *grp = iter_val(&iter);
- more = iter_next(&iter);
- if (grp->accessed) {
- grp->accessed = 0;
- continue;
- }
- /* If we can't unload, it's no big deal. We'll do it later. */
- ilk_grp_unload(grp, sys);
- }
- }
- Unfy_stat
- ilk_srch(Ilk_sys *sys, Rls_srch **srch_ref, Unfy_term *term,
- int *limit, Rls_info *info)
- {
- Unfy_stat stat;
- ++sys->srch_cnt;
- stat = rls_srch_limit(srch_ref, term, NULL, limit,
- sys->lib->bend, info, sys, &sys->lib->rec);
- switch (stat) {
- case UNFY_YES:
- if (!(sys->srch_cnt % GRP_CLEAN_CYCLE) && !sys->lib->testing)
- clean_grps(sys);
- if (!(sys->srch_cnt % SRCH_CLEAN_CYCLE) && !sys->lib->testing)
- clean_srchs(sys);
- break;
- case UNFY_ERR:
- /* Since rls doesn't use nit err */
- if (!sys->lib->err.occured)
- err_cust(&sys->lib->err, "Failed searching");
- /* fallthru */
- case UNFY_NO:
- --sys->srch_cnt;
- break;
- }
- return stat;
- }
- static int
- srch_extract_meta(Rls_srch *srch, Ilk_sys *sys, uint64_t srch_cnt)
- {
- Rls_srch **srch_ref = &srch;
- Ilk_meta meta;
- ilk_meta_init(&meta, srch_cnt, 0);
- while (*srch_ref) {
- ilk_meta_get(&meta, srch_ref, sys);
- if (!*srch_ref)
- break;
- if (ilk_meta_save(sys, &meta) < 0) {
- ilk_meta_dispose(&meta);
- return -1;
- }
- rls_srch_next(srch_ref);
- }
- ilk_meta_dispose(&meta);
- return 0;
- }
- static int
- srch_update_meta(Rls_srch *srch, Ilk_sys *sys, uint64_t srch_cnt)
- {
- Ilk_more *more;
- uint64_t tmp;
- if (!srch)
- return 0;
- more = srch->rule->dat;
- tmp = more->srch_cnt;
- /* tmp == 0 => a priori, it has no meta file */
- if (tmp != srch_cnt && tmp) {
- Ilk_meta_path path;
- ilk_meta_path(path, srch->rule->id);
- if (ilk_path_meta_dep(sys, path, srch_cnt) < 0)
- return -1;
- }
- more->srch_cnt = srch_cnt;
- rls_srch_next(&srch);
- if (srch_update_meta(srch, sys, srch_cnt) < 0) {
- more->srch_cnt = tmp;
- return -1;
- }
- more->srch_cnt = tmp;
- return 0;
- }
- int
- ilk_srch_save(Ilk_sys *sys, Rls_srch *srch, uint64_t srch_cnt)
- {
- size_t pos = 0;
- Ilk_srch_path path;
- Nit_file file;
- Nit_err tmp;
- if (srch_extract_meta(srch, sys, srch_cnt) < 0)
- return -1;
- if (srch_update_meta(srch, sys, srch_cnt) < 0)
- return -1;
- if (rlsp_srch_ser(srch, &sys->lib->buf.bytes, &sys->lib->buf.size, &pos)) {
- err_cust(&sys->lib->err, "Failed to serialize srch");
- return -1;
- }
- ilk_srch_path(path, srch_cnt);
- switch (file_exists(&sys->dir, path, &sys->lib->err)) {
- case 0:
- break;
- case 1:
- err_cust(&sys->lib->err, "Srch file already exists");
- /* fallthru */
- default:
- goto err_no_file;
- }
- if (dir_sub(&sys->dir, path, &sys->lib->err) < 0 ||
- file_open(&file, &sys->dir, path, &sys->lib->err) < 0)
- goto err_no_file;
- if (file_set(&file, sys->lib->buf.bytes, pos, &sys->lib->err) < 0 ||
- file_close(&file, &sys->lib->err) < 0)
- goto err_file;
- return 0;
- err_file:
- file_close(&file, &tmp);
- err_no_file:
- err_where(&sys->lib->err, path);
- return -1;
- }
- int
- ilk_srch_get(Rls_srch **srch_ref, uint64_t srch_cnt, Ilk_sys *sys)
- {
- if ((*srch_ref = map_get(&sys->srchs, &srch_cnt, sizeof(srch_cnt))))
- return 0;
- return ilk_srch_load(srch_ref, srch_cnt, sys);
- }
- int
- ilk_srch_load(Rls_srch **srch_ref, uint64_t srch_cnt, Ilk_sys *sys)
- {
- Ilk_rule_path path;
- ilk_srch_path(path, srch_cnt);
- if (ilk_path_srch(srch_ref, path, sys) < 0)
- return -1;
- if (map_add(&sys->srchs, &srch_cnt, sizeof(srch_cnt),
- *srch_ref, &sys->lib->stack) < 0) {
- err_cust(&sys->lib->err, "Failed to add srch");
- rls_recycle_srch(&sys->lib->rec, *srch_ref);
- *srch_ref = NULL;
- return -1;
- }
- return 0;
- }
- int
- ilk_srch_unload(uint64_t srch_cnt, Ilk_sys *sys)
- {
- Rls_srch *srch = map_get(&sys->srchs, &srch_cnt, sizeof(srch_cnt));
- if (!srch) {
- err_cust(&sys->lib->err, "Srch not found in unloading");
- return -1;
- }
- if (ilk_srch_save(sys, srch, srch_cnt) < 0)
- return -1;
- map_remove(&sys->srchs, &srch_cnt, sizeof(srch_cnt), &sys->lib->stack);
- rls_recycle_srch(&sys->lib->rec, srch);
- return 0;
- }
|