1 | /* Listpack -- A lists of strings serialization format |
2 | * |
3 | * This file implements the specification you can find at: |
4 | * |
5 | * https://github.com/antirez/listpack |
6 | * |
7 | * Copyright (c) 2017, Salvatore Sanfilippo <antirez at gmail dot com> |
8 | * All rights reserved. |
9 | * |
10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions are met: |
12 | * |
13 | * * Redistributions of source code must retain the above copyright notice, |
14 | * this list of conditions and the following disclaimer. |
15 | * * Redistributions in binary form must reproduce the above copyright |
16 | * notice, this list of conditions and the following disclaimer in the |
17 | * documentation and/or other materials provided with the distribution. |
18 | * * Neither the name of Redis nor the names of its contributors may be used |
19 | * to endorse or promote products derived from this software without |
20 | * specific prior written permission. |
21 | * |
22 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
23 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
24 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
25 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
26 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
27 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
28 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
29 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
30 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
31 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
32 | * POSSIBILITY OF SUCH DAMAGE. |
33 | */ |
34 | |
35 | #ifndef __LISTPACK_H |
36 | #define __LISTPACK_H |
37 | |
38 | #include <stdlib.h> |
39 | #include <stdint.h> |
40 | |
41 | #define LP_INTBUF_SIZE 21 /* 20 digits of -2^63 + 1 null term = 21. */ |
42 | |
43 | /* lpInsert() where argument possible values: */ |
44 | #define LP_BEFORE 0 |
45 | #define LP_AFTER 1 |
46 | #define LP_REPLACE 2 |
47 | |
48 | /* Each entry in the listpack is either a string or an integer. */ |
49 | typedef struct { |
50 | /* When string is used, it is provided with the length (slen). */ |
51 | unsigned char *sval; |
52 | uint32_t slen; |
53 | /* When integer is used, 'sval' is NULL, and lval holds the value. */ |
54 | long long lval; |
55 | } listpackEntry; |
56 | |
57 | unsigned char *lpNew(size_t capacity); |
58 | void lpFree(unsigned char *lp); |
59 | unsigned char* lpShrinkToFit(unsigned char *lp); |
60 | unsigned char *lpInsertString(unsigned char *lp, unsigned char *s, uint32_t slen, |
61 | unsigned char *p, int where, unsigned char **newp); |
62 | unsigned char *lpInsertInteger(unsigned char *lp, long long lval, |
63 | unsigned char *p, int where, unsigned char **newp); |
64 | unsigned char *lpPrepend(unsigned char *lp, unsigned char *s, uint32_t slen); |
65 | unsigned char *lpPrependInteger(unsigned char *lp, long long lval); |
66 | unsigned char *lpAppend(unsigned char *lp, unsigned char *s, uint32_t slen); |
67 | unsigned char *lpAppendInteger(unsigned char *lp, long long lval); |
68 | unsigned char *lpReplace(unsigned char *lp, unsigned char **p, unsigned char *s, uint32_t slen); |
69 | unsigned char *lpReplaceInteger(unsigned char *lp, unsigned char **p, long long lval); |
70 | unsigned char *lpDelete(unsigned char *lp, unsigned char *p, unsigned char **newp); |
71 | unsigned char *lpDeleteRangeWithEntry(unsigned char *lp, unsigned char **p, unsigned long num); |
72 | unsigned char *lpDeleteRange(unsigned char *lp, long index, unsigned long num); |
73 | unsigned char *lpMerge(unsigned char **first, unsigned char **second); |
74 | unsigned long lpLength(unsigned char *lp); |
75 | unsigned char *lpGet(unsigned char *p, int64_t *count, unsigned char *intbuf); |
76 | unsigned char *lpGetValue(unsigned char *p, unsigned int *slen, long long *lval); |
77 | unsigned char *lpFind(unsigned char *lp, unsigned char *p, unsigned char *s, uint32_t slen, unsigned int skip); |
78 | unsigned char *lpFirst(unsigned char *lp); |
79 | unsigned char *lpLast(unsigned char *lp); |
80 | unsigned char *lpNext(unsigned char *lp, unsigned char *p); |
81 | unsigned char *lpPrev(unsigned char *lp, unsigned char *p); |
82 | size_t lpBytes(unsigned char *lp); |
83 | unsigned char *lpSeek(unsigned char *lp, long index); |
84 | typedef int (*listpackValidateEntryCB)(unsigned char *p, unsigned int head_count, void *userdata); |
85 | int lpValidateIntegrity(unsigned char *lp, size_t size, int deep, |
86 | listpackValidateEntryCB entry_cb, void *cb_userdata); |
87 | unsigned char *lpValidateFirst(unsigned char *lp); |
88 | int lpValidateNext(unsigned char *lp, unsigned char **pp, size_t lpbytes); |
89 | unsigned int lpCompare(unsigned char *p, unsigned char *s, uint32_t slen); |
90 | void lpRandomPair(unsigned char *lp, unsigned long total_count, listpackEntry *key, listpackEntry *val); |
91 | void lpRandomPairs(unsigned char *lp, unsigned int count, listpackEntry *keys, listpackEntry *vals); |
92 | unsigned int lpRandomPairsUnique(unsigned char *lp, unsigned int count, listpackEntry *keys, listpackEntry *vals); |
93 | int lpSafeToAdd(unsigned char* lp, size_t add); |
94 | void lpRepr(unsigned char *lp); |
95 | |
96 | #ifdef REDIS_TEST |
97 | int listpackTest(int argc, char *argv[], int flags); |
98 | #endif |
99 | |
100 | #endif |
101 | |