github.com/moontrade/nogc@v0.1.7/collections/wormhole/kv.h (about)

     1  /*
     2   * Copyright (c) 2016--2021  Wu, Xingbo <wuxb45@gmail.com>
     3   *
     4   * All rights reserved. No warranty, explicit or implicit, provided.
     5   */
     6  #pragma once
     7  
     8  #ifdef __cplusplus
     9  extern "C" {
    10  #endif
    11  
    12  // crc32c {{{
    13  #define KV_CRC32C_SEED ((0xDEADBEEFu))
    14  
    15    extern u32
    16  kv_crc32c(const void * const ptr, u32 len);
    17  
    18    extern u64
    19  kv_crc32c_extend(const u32 crc32c);
    20  // }}} crc32c
    21  
    22  // kv {{{
    23  
    24  // struct {{{
    25  /*
    26   * Some internal union names can be ignored:
    27   * struct kv {
    28   *   u32 klen;
    29   *   u32 vlen;
    30   *   u64 hash;
    31   *   u8 kv[];
    32   * };
    33   */
    34  struct kv {
    35    union { // the first u64
    36      u64 kvlen;
    37      struct {
    38        u32 klen;
    39        union { u32 vlen; u32 refcnt; };
    40      };
    41    };
    42    union {
    43      u64 hash; // hashvalue of the key
    44      u64 priv; // can hide a value here if hash is not used
    45      void * privptr;
    46      struct { u32 hashlo; u32 hashhi; }; // little endian
    47      struct { u32 privlo; u32 privhi; };
    48    };
    49    u8 kv[0];  // len(kv) == klen + vlen
    50  } __attribute__((packed));
    51  
    52  struct kref {
    53    u32 len;
    54    union { u32 hash32; u32 priv; };
    55    const u8 * ptr;
    56  } __attribute__((packed));
    57  
    58  struct kvref {
    59    const u8 * kptr; // read-only
    60    const u8 * vptr; // read-only
    61    struct kv hdr; // hdr.kv[] is invalid
    62  };
    63  // }}} struct
    64  
    65  // kv {{{
    66  typedef int  (*kv_kv_cmp_func)(const struct kv *, const struct kv *);
    67  
    68    extern size_t
    69  kv_size(const struct kv * const kv);
    70  
    71    extern size_t
    72  kv_size_align(const struct kv * const kv, const u64 align);
    73  
    74    extern size_t
    75  key_size(const struct kv * const key);
    76  
    77    extern size_t
    78  key_size_align(const struct kv * const key, const u64 align);
    79  
    80    extern void
    81  kv_update_hash(struct kv * const kv);
    82  
    83    extern void
    84  kv_refill_value(struct kv * const kv, const void * const value, const u32 vlen);
    85  
    86    extern void
    87  kv_refill(struct kv * const kv, const void * const key, const u32 klen,
    88      const void * const value, const u32 vlen);
    89  
    90    extern void
    91  kv_refill_str(struct kv * const kv, const char * const key,
    92      const void * const value, const u32 vlen);
    93  
    94    extern void
    95  kv_refill_str_str(struct kv * const kv, const char * const key,
    96      const char * const value);
    97  
    98  // the u64 key is filled in big-endian byte order
    99    extern void
   100  kv_refill_u64(struct kv * const kv, const u64 key, const void * const value, const u32 vlen);
   101  
   102    extern void
   103  kv_refill_hex32(struct kv * const kv, const u32 hex, const void * const value, const u32 vlen);
   104  
   105    extern void
   106  kv_refill_hex64(struct kv * const kv, const u64 hex, const void * const value, const u32 vlen);
   107  
   108    extern void
   109  kv_refill_hex64_klen(struct kv * const kv, const u64 hex, const u32 klen,
   110      const void * const value, const u32 vlen);
   111  
   112    extern void
   113  kv_refill_kref(struct kv * const kv, const struct kref * const kref);
   114  
   115    extern void
   116  kv_refill_kref_v(struct kv * const kv, const struct kref * const kref,
   117      const void * const value, const u32 vlen);
   118  
   119    extern struct kref
   120  kv_kref(const struct kv * const key);
   121  
   122    extern struct kv *
   123  kv_create(const void * const key, const u32 klen, const void * const value, const u32 vlen);
   124  
   125    extern struct kv *
   126  kv_create_str(const char * const key, const void * const value, const u32 vlen);
   127  
   128    extern struct kv *
   129  kv_create_str_str(const char * const key, const char * const value);
   130  
   131    extern struct kv *
   132  kv_create_kref(const struct kref * const kref, const void * const value, const u32 vlen);
   133  
   134  // a static kv with klen == 0
   135    extern const struct kv *
   136  kv_null(void);
   137  
   138    extern struct kv *
   139  kv_dup(const struct kv * const kv);
   140  
   141    extern struct kv *
   142  kv_dup_key(const struct kv * const kv);
   143  
   144    extern struct kv *
   145  kv_dup2(const struct kv * const from, struct kv * const to);
   146  
   147    extern struct kv *
   148  kv_dup2_key(const struct kv * const from, struct kv * const to);
   149  
   150    extern struct kv *
   151  kv_dup2_key_prefix(const struct kv * const from, struct kv * const to, const u32 plen);
   152  
   153    extern bool
   154  kv_match(const struct kv * const key1, const struct kv * const key2);
   155  
   156    extern bool
   157  kv_match_hash(const struct kv * const key1, const struct kv * const key2);
   158  
   159    extern bool
   160  kv_match_full(const struct kv * const kv1, const struct kv * const kv2);
   161  
   162    extern bool
   163  kv_match_kv128(const struct kv * const sk, const u8 * const kv128);
   164  
   165    extern int
   166  kv_compare(const struct kv * const kv1, const struct kv * const kv2);
   167  
   168    extern int
   169  kv_k128_compare(const struct kv * const sk, const u8 * const k128);
   170  
   171    extern int
   172  kv_kv128_compare(const struct kv * const sk, const u8 * const kv128);
   173  
   174    extern void
   175  kv_qsort(struct kv ** const kvs, const size_t nr);
   176  
   177    extern u32
   178  kv_key_lcp(const struct kv * const key1, const struct kv * const key2);
   179  
   180    extern u32
   181  kv_key_lcp_skip(const struct kv * const key1, const struct kv * const key2, const u32 lcp0);
   182  
   183    extern void
   184  kv_psort(struct kv ** const kvs, const u64 nr, const u64 tlo, const u64 thi);
   185  
   186    extern void *
   187  kv_vptr(struct kv * const kv);
   188  
   189    extern void *
   190  kv_kptr(struct kv * const kv);
   191  
   192    extern const void *
   193  kv_vptr_c(const struct kv * const kv);
   194  
   195    extern const void *
   196  kv_kptr_c(const struct kv * const kv);
   197  
   198    extern void
   199  kv_print(const struct kv * const kv, const char * const cmd, FILE * const out);
   200  // }}} kv
   201  
   202  // mm {{{
   203  typedef struct kv * (* kvmap_mm_in_func)(struct kv * kv, void * priv);
   204  typedef struct kv * (* kvmap_mm_out_func)(struct kv * kv, struct kv * out);
   205  typedef void        (* kvmap_mm_free_func)(struct kv * kv, void * priv);
   206  
   207  // manage internal kv data of kvmap
   208  struct kvmap_mm {
   209    // to create a private copy of "kv"
   210    // see put() functions
   211    kvmap_mm_in_func in;
   212    // to duplicate a private copy of "kv" to "out"
   213    // see get() and iter_peek() functions
   214    kvmap_mm_out_func out;
   215    // to free a kv
   216    // see del() and put() functions
   217    kvmap_mm_free_func free;
   218    void * priv;
   219  };
   220  
   221    extern struct kv *
   222  kvmap_mm_in_noop(struct kv * const kv, void * const priv);
   223  
   224    extern struct kv *
   225  kvmap_mm_out_noop(struct kv * const kv, struct kv * const out);
   226  
   227    extern void
   228  kvmap_mm_free_noop(struct kv * const kv, void * const priv);
   229  
   230    extern struct kv *
   231  kvmap_mm_in_dup(struct kv * const kv, void * const priv);
   232  
   233    extern struct kv *
   234  kvmap_mm_out_dup(struct kv * const kv, struct kv * const out);
   235  
   236    extern void
   237  kvmap_mm_free_free(struct kv * const kv, void * const priv);
   238  
   239  // the default mm
   240  extern const struct kvmap_mm kvmap_mm_dup; // in:Dup, out:Dup, free:Free
   241  extern const struct kvmap_mm kvmap_mm_ndf; // in:Noop, out:Dup, free:Free
   242  // }}} mm
   243  
   244  // ref {{{
   245  typedef int (*kref_kv_cmp_func)(const struct kref *, const struct kv *);
   246  
   247  // ptr and len only
   248    extern void
   249  kref_ref_raw(struct kref * const kref, const u8 * const ptr, const u32 len);
   250  
   251  // this calculates hash32
   252    extern void
   253  kref_ref_hash32(struct kref * const kref, const u8 * const ptr, const u32 len);
   254  
   255    extern void
   256  kref_update_hash32(struct kref * const kref);
   257  
   258    extern void
   259  kref_ref_kv(struct kref * const kref, const struct kv * const kv);
   260  
   261    extern void
   262  kref_ref_kv_hash32(struct kref * const kref, const struct kv * const kv);
   263  
   264    extern bool
   265  kref_match(const struct kref * const k1, const struct kref * const k2);
   266  
   267    extern bool
   268  kref_kv_match(const struct kref * const kref, const struct kv * const k);
   269  
   270    extern int
   271  kref_compare(const struct kref * const kref1, const struct kref * const kref2);
   272  
   273    extern int
   274  kref_kv_compare(const struct kref * const kref, const struct kv * const k);
   275  
   276    extern u32
   277  kref_lcp(const struct kref * const k1, const struct kref * const k2);
   278  
   279    extern u32
   280  kref_kv_lcp(const struct kref * const kref, const struct kv * const kv);
   281  
   282    extern int
   283  kref_k128_compare(const struct kref * const sk, const u8 * const k128);
   284  
   285    extern int
   286  kref_kv128_compare(const struct kref * const sk, const u8 * const kv128);
   287  
   288    extern const struct kref *
   289  kref_null(void);
   290  
   291    extern void
   292  kvref_ref_kv(struct kvref * const ref, struct kv * const kv);
   293  
   294    extern struct kv *
   295  kvref_dup2_kv(struct kvref * const ref, struct kv * const to);
   296  
   297    extern struct kv *
   298  kvref_dup2_key(struct kvref * const ref, struct kv * const to);
   299  
   300    extern int
   301  kvref_kv_compare(const struct kvref * const ref, const struct kv * const kv);
   302  // }}} ref
   303  
   304  // kv128 {{{
   305    extern size_t
   306  kv128_estimate_kv(const struct kv * const kv);
   307  
   308    extern u8 *
   309  kv128_encode_kv(const struct kv * const kv, u8 * const out, size_t * const pesize);
   310  
   311    extern struct kv *
   312  kv128_decode_kv(const u8 * const ptr, struct kv * const out, size_t * const pesize);
   313  
   314    extern size_t
   315  kv128_size(const u8 * const ptr);
   316  // }}} kv128
   317  
   318  // }}} kv
   319  
   320  // kvmap {{{
   321  
   322  // kvmap_api {{{
   323  typedef void (* kv_inp_func)(struct kv * const curr, void * const priv);
   324  
   325  // the merge function should:
   326  // 1: return NULL if the origin kv is not changed at all
   327  // 2: return kv0 if updates has been applied in-place
   328  // 3: return a different kv if the original kv must be replaced
   329  // In an in-memory kvmap, 2==1 and no further action is needed
   330  // In a persistent kv store with a memtable, 2 will need an insertion if kv0 is not from the memtable
   331  typedef struct kv * (* kv_merge_func)(struct kv * const kv0, void * const priv);
   332  
   333  struct kvmap_api {
   334    // feature bits
   335    bool hashkey; // true: caller needs to provide correct hash in kv/kref
   336    bool ordered; // true: has iter_seek
   337    bool threadsafe; // true: support thread_safe access
   338    bool readonly; // true: no put() and del()
   339    bool irefsafe; // true: iter's kref/kvref can be safely accessed after iter_seek/iter_skip/iter_park
   340    bool unique; // provide unique keys, especially for iterators
   341    bool refpark; // ref has park() and resume()
   342    bool async; // XXX for testing KVell
   343  
   344    // put (aka put/upsert): return true on success; false on error
   345    // mm.in() controls how things move into the kvmap; the default mm make a copy with malloc()
   346    // mm.free() controls how old kv get disposed when replaced
   347    bool        (* put)     (void * const ref, struct kv * const kv);
   348    // get: search and return a kv if found, or NULL if not
   349    // with the default mm: malloc() if out == NULL; otherwise, use out as buffer
   350    // with custom kvmap_mm: mm.out() controls buffer; use with caution
   351    // caller should use the returned ptr even if out is provided
   352    struct kv * (* get)     (void * const ref, const struct kref * const key, struct kv * const out);
   353    // probe: return true on found, false on not found
   354    bool        (* probe)   (void * const ref, const struct kref * const key);
   355    // del: return true on something deleted, false on not found
   356    // mm.free() controls how old kv get disposed when replaced
   357    bool        (* del)     (void * const ref, const struct kref * const key);
   358    // inp: inplace operation if key exists; otherwise return false; uf() is always executed even with NULL key
   359    // inpr/inpw acquires r/w locks respectively.
   360    // Note that in inpw() you can only change the value.
   361    bool        (* inpr)    (void * const ref, const struct kref * const key, kv_inp_func uf, void * const priv);
   362    bool        (* inpw)    (void * const ref, const struct kref * const key, kv_inp_func uf, void * const priv);
   363    // merge: put+callback on old/new keys; another name: read-modify-write
   364    // return true if successfull; return false on error
   365    bool        (* merge)   (void * const ref, const struct kref * const key, kv_merge_func uf, void * const priv);
   366    // delete-range: delete all keys from start (inclusive) to end (exclusive)
   367    u64         (* delr)    (void * const ref, const struct kref * const start, const struct kref * const end);
   368    // make everything persist; for persistent maps only
   369    void        (* sync)    (void * const ref);
   370  
   371    // general guidelines for thread-safe iters:
   372    // - it is assumed that the key under the cursor is locked/freezed/immutable
   373    // - once created one must call iter_seek to make it valid
   374    // - the ownership of ref is given to the iter so ref should not be used until iter_destroy
   375    // - creating and use more than one iter based on a ref can cause deadlocks
   376    void *      (* iter_create)   (void * const ref);
   377    // move the cursor to the first key >= search-key;
   378    void        (* iter_seek)     (void * const iter, const struct kref * const key);
   379    // check if the cursor points to a valid key
   380    bool        (* iter_valid)    (void * const iter);
   381    // return the current key; copy to out if (out != NULL)
   382    // mm.out() controls copy-out
   383    struct kv * (* iter_peek)     (void * const iter, struct kv * const out);
   384    // similar to peek but does not copy; return false if iter is invalid
   385    bool        (* iter_kref)     (void * const iter, struct kref * const kref);
   386    // similar to iter_kref but also provide the value
   387    bool        (* iter_kvref)    (void * const iter, struct kvref * const kvref);
   388    // iter_retain makes kref or kvref of the current iter remain valid until released
   389    // the returned opaque pointer should be provided when releasing the hold
   390    u64         (* iter_retain)   (void * const iter);
   391    void        (* iter_release)  (void * const iter, const u64 opaque);
   392    // skip one element
   393    void        (* iter_skip1)    (void * const iter);
   394    // skip nr elements
   395    void        (* iter_skip)     (void * const iter, const u32 nr);
   396    // iter_next == iter_peek + iter_skip1
   397    struct kv * (* iter_next)     (void * const iter, struct kv * const out);
   398    // perform inplace opeation if the current key is valid; return false if no current key
   399    // the uf() is always executed even with NULL key
   400    bool        (* iter_inp)      (void * const iter, kv_inp_func uf, void * const priv);
   401    // invalidate the iter to release any resources or locks
   402    // afterward, must call seek() again before accessing data
   403    void        (* iter_park)     (void * const iter);
   404    // destroy iter
   405    void        (* iter_destroy)  (void * const iter);
   406  
   407    // misc:
   408    // create refs for maps if required; always use use kvmap_ref() and kvmap_unref()
   409    // if there are ref/unref functions, ref-ptr should be used as map for all kv operations
   410    void *      (* ref)     (void * map);
   411    // return the original map
   412    void *      (* unref)   (void * ref);
   413    // pause access without unref; must call resume later before access index again
   414    void        (* park)    (void * ref);
   415    // resume access of ref; must be paired with a park()
   416    void        (* resume)  (void * ref);
   417  
   418    // UNSAFE functions:
   419    // empty the map
   420    void        (* clean)   (void * map);
   421    // erase everything
   422    void        (* destroy) (void * map);
   423    // for debugging
   424    void        (* fprint)  (void * map, FILE * const out);
   425  };
   426  
   427  // registry
   428  struct kvmap_api_reg {
   429    int nargs; // number of arguments after name
   430    const char * name;
   431    const char * args_msg; // see ...helper_message
   432    // multiple apis may share one create function
   433    // arguments: name (e.g., "rdb"), mm (usually NULL), the remaining args
   434    void * (*create)(const char *, const struct kvmap_mm *, char **);
   435    const struct kvmap_api * api;
   436  };
   437  
   438  // call this function to register a kvmap_api
   439    extern void
   440  kvmap_api_register(const int nargs, const char * const name, const char * const args_msg,
   441      void * (*create)(const char *, const struct kvmap_mm *, char **), const struct kvmap_api * const api);
   442  
   443    extern void
   444  kvmap_api_helper_message(void);
   445  
   446    extern int
   447  kvmap_api_helper(int argc, char ** const argv, const struct kvmap_mm * const mm,
   448      const struct kvmap_api ** const api_out, void ** const map_out);
   449  // }}} kvmap_api
   450  
   451  // helpers {{{
   452    extern void
   453  kvmap_inp_steal_kv(struct kv * const kv, void * const priv);
   454  
   455    extern void *
   456  kvmap_ref(const struct kvmap_api * const api, void * const map);
   457  
   458    extern void *
   459  kvmap_unref(const struct kvmap_api * const api, void * const ref);
   460  
   461    extern struct kv *
   462  kvmap_kv_get(const struct kvmap_api * const api, void * const ref,
   463      const struct kv * const key, struct kv * const out);
   464  
   465    extern bool
   466  kvmap_kv_probe(const struct kvmap_api * const api, void * const ref,
   467      const struct kv * const key);
   468  
   469    extern bool
   470  kvmap_kv_put(const struct kvmap_api * const api, void * const ref,
   471      struct kv * const kv);
   472  
   473    extern bool
   474  kvmap_kv_del(const struct kvmap_api * const api, void * const ref,
   475      const struct kv * const key);
   476  
   477    extern bool
   478  kvmap_kv_inpr(const struct kvmap_api * const api, void * const ref,
   479      const struct kv * const key, kv_inp_func uf, void * const priv);
   480  
   481    extern bool
   482  kvmap_kv_inpw(const struct kvmap_api * const api, void * const ref,
   483      const struct kv * const key, kv_inp_func uf, void * const priv);
   484  
   485    extern bool
   486  kvmap_kv_merge(const struct kvmap_api * const api, void * const ref,
   487      const struct kv * const key, kv_merge_func uf, void * const priv);
   488  
   489    extern u64
   490  kvmap_kv_delr(const struct kvmap_api * const api, void * const ref,
   491      const struct kv * const start, const struct kv * const end);
   492  
   493    extern void
   494  kvmap_kv_iter_seek(const struct kvmap_api * const api, void * const iter,
   495      const struct kv * const key);
   496  
   497    extern struct kv *
   498  kvmap_raw_get(const struct kvmap_api * const api, void * const ref,
   499      const u32 len, const u8 * const ptr, struct kv * const out);
   500  
   501    extern bool
   502  kvmap_raw_probe(const struct kvmap_api * const api, void * const ref,
   503      const u32 len, const u8 * const ptr);
   504  
   505    extern bool
   506  kvmap_raw_del(const struct kvmap_api * const api, void * const ref,
   507      const u32 len, const u8 * const ptr);
   508  
   509    extern bool
   510  kvmap_raw_inpr(const struct kvmap_api * const api, void * const ref,
   511      const u32 len, const u8 * const ptr, kv_inp_func uf, void * const priv);
   512  
   513    extern bool
   514  kvmap_raw_inpw(const struct kvmap_api * const api, void * const ref,
   515      const u32 len, const u8 * const ptr, kv_inp_func uf, void * const priv);
   516  
   517    extern void
   518  kvmap_raw_iter_seek(const struct kvmap_api * const api, void * const iter,
   519      const u32 len, const u8 * const ptr);
   520  
   521    extern u64
   522  kvmap_dump_keys(const struct kvmap_api * const api, void * const map, const int fd);
   523  // }}} helpers
   524  
   525  // }}} kvmap
   526  
   527  #ifdef __cplusplus
   528  }
   529  #endif
   530  // vim:fdm=marker