123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342 |
- #include <rid.h>
- #include <stdint.h>
- #include <stdlib.h>
- #define NIT_SHORT_NAMES
- #include <nit/macros.h>
- #include <nit/palloc.h>
- #include <nit/list.h>
- #include <nit/set.h>
- #include <nit/map.h>
- #include <nit/buf.h>
- #include <nit/gap.h>
- #include <nit/crs.h>
- #include "aas.h"
- Aas_rule *
- aas_rule_new(const Rid id, const Rid add_id, int64_t size)
- {
- Aas_rule *rule = palloc(rule);
- pcheck(rule, NULL);
- if (gap_init(&rule->vals, size) < 0) {
- free(rule);
- return NULL;
- }
- rule->next = NULL;
- rid_set(rule->id, id);
- rid_set(rule->add_id, add_id);
- return rule;
- }
- void
- aas_rule_free(Aas_rule *rule)
- {
- gap_dispose(&rule->vals);
- free(rule);
- }
- static int
- gap_contains(Nit_crs *crs, Nit_gap *gap, const Rid id)
- {
- Rid crs_id;
- crs_init(crs, gap, 0);
- while (!crs_movef(crs, sizeof(Rid))) {
- int cmp_val;
- crs_read(crs, crs_id, sizeof(Rid));
- if (!(cmp_val = rid_cmp(id, crs_id)))
- return 1;
- if (cmp_val > 0) {
- crs_moveb(crs, sizeof(Rid));
- return 0;
- }
- }
- return 0;
- }
- int
- aas_rule_add(Aas_rule *rule, const Rid id)
- {
- Nit_crs crs;
- if (gap_contains(&crs, &rule->vals, id))
- return 1;
- return crs_write(&crs, id, sizeof(Rid));
- }
- int
- aas_rule_remove(Aas_rule *rule, const Rid id)
- {
- Nit_crs crs;
- if (!gap_contains(&crs, &rule->vals, id))
- return 1;
- crs_erase(&crs, sizeof(Rid));
- return 0;
- }
- int
- aas_rule_same(Aas_rule *rule1, Aas_rule *rule2)
- {
- Nit_crs crs1;
- Nit_crs crs2;
- if (rid_cmp(rule1->add_id, rule2->add_id))
- return 0;
- crs_init(&crs1, &rule1->vals, 0);
- crs_init(&crs2, &rule2->vals, 0);
- while (1) {
- int move = crs_movef(&crs1, sizeof(Rid));
- Rid id1;
- Rid id2;
- if (move != crs_movef(&crs2, sizeof(Rid)))
- return 0;
- if (move < 0)
- break;
- crs_read(&crs1, id1, sizeof(Rid));
- crs_read(&crs2, id2, sizeof(Rid));
- if (rid_cmp(id1, id2))
- return 0;
- }
- return 1;
- }
- int
- aas_set_init(Aas_set *set, Aas_rule *rules, unsigned int sequence)
- {
- if (map_init(&set->vals, sequence) < 0)
- return -1;
- set->rules = rules;
- return 0;
- }
- static void
- set_free_func(void *key, void *val, void *extra)
- {
- (void) extra;
- (void) key;
- gap_free(val);
- }
- void
- aas_set_dispose(Aas_set *set, Nit_entry **entries)
- {
- Aas_rule *rules = set->rules;
- while (rules) {
- Aas_rule *tmp = rules;
- rules = rules->next;
- aas_rule_free(tmp);
- }
- map_recycle(&set->vals, set_free_func, NULL, entries);
- map_dispose(&set->vals);
- }
- Aas_set *
- aas_set_new(Aas_rule *rules, unsigned int sequence)
- {
- Aas_set *set = palloc(set);
- pcheck(set, NULL);
- if (aas_set_init(set, rules, sequence) < 0){
- free(set);
- return NULL;
- }
- return set;
- }
- void
- aas_set_free(Aas_set *set, Nit_entry **entries)
- {
- aas_set_dispose(set, entries);
- free(set);
- }
- static int
- vals_contains(Nit_map *set_vals, Nit_gap *rule_vals)
- {
- Nit_crs crs;
- crs_init(&crs, rule_vals, 0);
- while (!crs_movef(&crs, sizeof(Rid))) {
- Rid crs_id;
- crs_read(&crs, crs_id, sizeof(Rid));
- if (!set_contains(set_vals, crs_id, sizeof(Rid)))
- return 0;
- }
- return 1;
- }
- static int
- evoke_rule(Aas_rule *rule, Aas_set *set, Nit_entry **entries)
- {
- if (!vals_contains(&set->vals, &rule->vals))
- return 0;
- if (aas_set_add(set, rule->add_id, rule->id, entries) < 0)
- return -1;
- return 0;
- }
- int
- aas_set_rule(Aas_set *set, Aas_rule *rule, Nit_entry **entries)
- {
- if (aas_set_match_rule(set, rule))
- return 1;
- rule->next = set->rules;
- set->rules = rule;
- return evoke_rule(rule, set, entries);
- }
- Aas_rule *
- aas_set_unrule(Aas_set *set, const Rid id, Nit_entry **entries)
- {
- Aas_rule **rules = &set->rules;
- for (; *rules; rules = &(*rules)->next)
- if (!rid_cmp((*rules)->id, id)) {
- Aas_rule *rule = *rules;
- *rules = rule->next;
- aas_set_remove(set, rule->add_id, rule->id, entries);
- return rule;
- }
- return NULL;
- }
- static int
- evoke_rules(Aas_set *set, const Rid id, Nit_entry **entries)
- {
- Aas_rule *rule = set->rules;
- Nit_crs crs;
- for (; rule; rule = rule->next)
- if (gap_contains(&crs, &rule->vals, id) &&
- evoke_rule(rule, set, entries) < 0)
- return -1;
- return 0;
- }
- int
- aas_set_add(Aas_set *set, const Rid id, const Rid rule_id, Nit_entry **entries)
- {
- Nit_gap *gap = map_get(&set->vals, id, sizeof(Rid));
- if (gap) {
- Nit_crs crs;
- if (gap_contains(&crs, gap, rule_id))
- return 0;
- return crs_write(&crs, rule_id, sizeof(Rid));
- }
- if (!(gap = gap_new(sizeof(Rid))))
- return -1;
- gap_write(gap, rule_id, sizeof(Rid));
- if (map_add(&set->vals, id, sizeof(Rid), gap, entries) < 0) {
- gap_free(gap);
- return -1;
- }
- if (evoke_rules(set, id, entries) < 0) {
- map_remove(&set->vals, id, sizeof(Rid), entries);
- gap_free(gap);
- return -1;
- }
- return 0;
- }
- static void
- unevoke_rules(Aas_set *set, const Rid id, Nit_entry **entries)
- {
- Aas_rule *rule = set->rules;
- Nit_crs crs;
- for (; rule; rule = rule->next)
- if (gap_contains(&crs, &rule->vals, id))
- aas_set_remove(set, rule->add_id, rule->id, entries);
- return;
- }
- void
- aas_set_remove(Aas_set *set, const Rid id, const Rid rule_id,
- Nit_entry **entries)
- {
- Nit_gap *gap = map_get(&set->vals, id, sizeof(Rid));
- Nit_crs crs;
- if (!gap || !gap_contains(&crs, gap, rule_id))
- return;
- crs_erase(&crs, sizeof(Rid));
- if (gap_len(gap))
- return;
- map_remove(&set->vals, id, sizeof(Rid), entries);
- gap_free(gap);
- unevoke_rules(set, id, entries);
- }
- Aas_rule *
- aas_set_match_rule(Aas_set *set, Aas_rule *rule)
- {
- Aas_rule *rules = set->rules;
- for (; rules; rules = rules->next)
- if (aas_rule_same(rule, rules))
- return rules;
- return NULL;
- }
- Aas_rule *
- aas_set_get_rule(Aas_set *set, const Rid id)
- {
- Aas_rule *rules = set->rules;
- for (; rules; rules = rules->next)
- if (!rid_cmp(rules->id, id))
- return rules;
- return NULL;
- }
|