#ifndef LSUP_KEYSET_H #define LSUP_KEYSET_H #include "core.h" typedef enum LSUP_KSFlag { LSUP_KS_CHECK_CAP = 1 << 0, LSUP_KS_CHECK_DUP = 1 << 1 } LSUP_KSFlag; typedef struct keyset { LSUP_TripleKey *data; size_t capacity; size_t cur; size_t free_i; float expand_ratio; } LSUP_Keyset; int LSUP_keyset_init(LSUP_Keyset *ks, size_t capacity, float expand_ratio); LSUP_Keyset *LSUP_keyset_new(size_t capacity, float expand_ratio); /** * Move cursor to a non-empty position. */ inline bool LSUP_keyset_seek(LSUP_Keyset* ks, size_t idx) { if (idx >= ks->free_i) return false; ks->cur = idx; return true; } inline size_t LSUP_keyset_size(LSUP_Keyset* ks) { return(ks->free_i); } inline size_t LSUP_keyset_tell(LSUP_Keyset* ks) { return(ks->cur); } inline const LSUP_TripleKey *LSUP_keyset_peek(LSUP_Keyset *ks) { return (const LSUP_TripleKey *)(ks->data + ks->cur); } inline bool LSUP_keyset_contains( const LSUP_Keyset *ks, const LSUP_TripleKey *val) { for (size_t i = 0; i < ks->free_i; i++) { // scan from the least to the most probable to match. if ( (*val)[2] == ks->data[i][2] && (*val)[0] == ks->data[i][0] && (*val)[1] == ks->data[i][1]) { return true; } } return false; } inline bool LSUP_keyset_next(LSUP_Keyset *ks) { if (ks->free_i > 0 && ks->cur < ks->free_i - 1) { ks->cur ++; return true; } return false; } /** * Resize the keyset capacity. * * Size cannot be smaller than `free_i`. Therefore, specifying a size of 0 will * always compact the keyset to the current occupied space. */ int LSUP_keyset_resize(LSUP_Keyset *ks, size_t new_size); /** * Add a single key. */ int LSUP_keyset_add( LSUP_Keyset *ks, const LSUP_TripleKey *val, LSUP_KSFlag flags); int LSUP_keyset_remove(LSUP_Keyset *ks, const LSUP_TripleKey *val); int LSUP_keyset_copy(const LSUP_Keyset *src, LSUP_Keyset *dest); int LSUP_keyset_sparse_copy(LSUP_Keyset *src, LSUP_Keyset *dest); int LSUP_keyset_lookup( LSUP_Keyset *ks, LSUP_Keyset *res, const LSUP_Key sk, const LSUP_Key pk, const LSUP_Key ok); /** * Set-theoretical union (ks1 ∪ ks2). * * The resulting Keyset is initialized beforehand and is not compacted. */ int LSUP_keyset_join(LSUP_Keyset *ks1, LSUP_Keyset *ks2, LSUP_Keyset *res); /** * Set-theoretical complement (ks1 \ ks2). * * The resulting Keyset is initialized beforehand and is not compacted. */ int LSUP_keyset_subtract(LSUP_Keyset *ks1, LSUP_Keyset *ks2, LSUP_Keyset *res); /** * Set-theoretical intersection (ks1 ∩ ks2). * * The resulting Keyset is initialized beforehand and is not compacted. */ int LSUP_keyset_intersect(LSUP_Keyset *ks1, LSUP_Keyset *ks2, LSUP_Keyset *res); /** * Disjunctive union (XOR) (ks1 ⊕ ks2). * * The resulting Keyset is initialized beforehand and is not compacted. */ int LSUP_keyset_xor(LSUP_Keyset *ks1, LSUP_Keyset *ks2, LSUP_Keyset *res); void LSUP_keyset_done(LSUP_Keyset *ks); void LSUP_keyset_free(LSUP_Keyset *ks); #endif