static fs_ptree_it *fs_backend_get_matches(fs_backend *be, fs_rid quad[4], int flags) { fs_ptree *pt = NULL; fs_rid pk; fs_rid pair[2]; if (flags & FS_BIND_BY_SUBJECT) { pt = fs_backend_get_ptree(be, quad[2], 0); pk = quad[1]; pair[0] = quad[0]; pair[1] = quad[3]; } else { pt = fs_backend_get_ptree(be, quad[2], 1); pk = quad[3]; pair[0] = quad[0]; pair[1] = quad[1]; } if (!pt) return NULL; return fs_ptree_search(pt, pk, pair); }
int fs_tbchain_it_next(fs_tbchain_it *it, fs_rid triple[3]) { if (!it) { fs_error(LOG_ERR, "fs_tbchain_it_next() passed NULL iterator"); return 0; } while (1) { if (it->node == 0) { triple[0] = FS_RID_NULL; triple[1] = FS_RID_NULL; triple[2] = FS_RID_NULL; if (it->superset) { fs_tbchain_clear_bit(it->tbc, it->chain, FS_TBCHAIN_SUPERSET); } return 0; } else if (it->node == 1) { fs_error(LOG_CRIT, "iterator ended up at B1"); triple[0] = FS_RID_NULL; triple[1] = FS_RID_NULL; triple[2] = FS_RID_NULL; return 0; } else if (it->pos >= it->tbc->data[it->node].length) { it->node = it->tbc->data[it->node].cont; it->pos = 0; } else if (it->tbc->data[it->node].data[it->pos][0] == FS_RID_GONE) { (it->pos)++; } else { int ok = 1; triple[0] = it->tbc->data[it->node].data[it->pos][0]; triple[1] = it->tbc->data[it->node].data[it->pos][1]; triple[2] = it->tbc->data[it->node].data[it->pos][2]; if (it->superset) { if (it->tbc->be) { fs_ptree *pt = fs_backend_get_ptree(it->tbc->be, triple[1], 0); fs_rid pair[2] = { it->model, triple[2] }; fs_ptree_it *pit = fs_ptree_search(pt, triple[0], pair); if (pit) { fs_rid dummy[2]; if (!fs_ptree_it_next(pit, dummy)) { ok = 0; } fs_ptree_it_free(pit); } else { ok = 0; } } else { fs_error(LOG_ERR, "backend pointer missing from tbchain, " "returning superset of results"); } } if (ok) { (it->pos)++; return 1; } else { it->tbc->data[it->node].data[it->pos][0] = FS_RID_GONE; fs_tbchain_set_bit(it->tbc, it->chain, FS_TBCHAIN_SPARSE); (it->pos)++; } } } }