1 /*
2  * Copyright (C) 2015-2017 Alibaba Group Holding Limited
3  */
4 
5 #ifndef KV_TYPES_H
6 #define KV_TYPES_H
7 
8 #include <stdint.h>
9 #include <stdlib.h>
10 #include <stddef.h>
11 #include <string.h>
12 
13 #include "kv_conf.h"
14 
15 #if (KV_BLOCK_SIZE_BITS >= 16) || (KV_TOTAL_SIZE >= 0x10000)
16 typedef uint32_t kv_size_t; /* If more than 64KB */
17 #else
18 typedef uint16_t kv_size_t;
19 #endif
20 
21 #ifdef _WIN32
22 #define KVMAGR_PKD
23 #else
24 #define KVMAGR_PKD __attribute__((packed))
25 #endif
26 
27 #ifdef _WIN32
28 #pragma pack(push, 1)
29 #endif
30 
31 /**
32  * Flash block header description
33  *
34  * magic: The magic number of block
35  * state: The state of the block
36  *
37  */
38 typedef struct _block_header_t
39 {
40     uint8_t magic;
41     uint8_t state;
42     uint8_t reserved[2];
43 } KVMAGR_PKD block_hdr_t;
44 
45 /**
46  * Key-value item header description
47  *
48  * magic:       The magic number of key-value item
49  * state:       The state of key-value item
50  * crc:         The crc-8 value of key-value item
51  * key_len:     The length of the key
52  * val_len:     The length of the value
53  * origin_off:  The origin item offset
54  *
55  */
56 typedef struct _item_header_t
57 {
58     uint8_t   magic;
59     uint8_t   state;
60     uint8_t   crc;
61     uint8_t   key_len;
62     uint16_t  val_len;
63     kv_size_t origin_off;
64 } KVMAGR_PKD item_hdr_t;
65 
66 #ifdef _WIN32
67 #pragma pack(pop)
68 #endif
69 
70 /**
71  * Defination of block information
72  *
73  * KV_BLOCK_SIZE:        block size, default is 4K bytes
74  * KV_BLOCK_NUMS:        numbers of blocks, must be bigger than KV_GC_RESERVED
75  * KV_BLOCK_OFF_MASK:    the mask of the block offset in kv store
76  * KV_BLOCK_HDR_SIZE:    The block header size, default is 4 bytes
77  *
78  */
79 #define KV_BLOCK_SIZE      (1 << KV_BLOCK_SIZE_BITS)
80 #define KV_BLOCK_NUMS      (KV_TOTAL_SIZE >> KV_BLOCK_SIZE_BITS)
81 #define KV_BLOCK_OFF_MASK ~(KV_BLOCK_SIZE - 1)
82 #define KV_BLOCK_HDR_SIZE  sizeof(block_hdr_t)
83 
84 /**
85  * Block state information
86  *
87  * KV_BLOCK_STATE_USED:  block is inused and without dirty data
88  * KV_BLOCK_STATE_CLEAN: block is clean, ready for used
89  * KV_BLOCK_STATE_DIRTY: block is inused and with dirty data
90  *
91  */
92 #define KV_BLOCK_STATE_USED  0xCC
93 #define KV_BLOCK_STATE_CLEAN 0xEE
94 #define KV_BLOCK_STATE_DIRTY 0x44
95 
96 #define INVALID_BLK_STATE(state) (((state) != KV_BLOCK_STATE_USED) &&  \
97                                   ((state) != KV_BLOCK_STATE_CLEAN) && \
98                                   ((state) != KV_BLOCK_STATE_DIRTY))
99 
100 /**
101  * Defination of item information
102  *
103  * KV_ITEM_HDR_SIZE: the item header size
104  * KV_ITEM_MAX_LEN:  the max length of the item
105  *
106  */
107 #define KV_ITEM_HDR_SIZE sizeof(item_hdr_t)
108 #define KV_ITEM_MAX_LEN  (KV_ITEM_HDR_SIZE + KV_MAX_KEY_LEN + KV_MAX_VAL_LEN)
109 
110 /**
111  * Item state information
112  *
113  * KV_ITEM_STATE_NORMAL: the item is valid
114  * KV_ITEM_STATE_DELETE: the item had beed deleted
115  *
116  */
117 #define KV_ITEM_STATE_NORMAL 0xEE
118 #define KV_ITEM_STATE_DELETE 0x00
119 
120 /**
121  * Defination of the key-value store information
122  *
123  * KV_STATE_OFFSET: the offset of block/item state in header structure
124  * KV_ALIGN_MASK:   the mask of the key-value store alignment
125  * KV_DELETE_FLAG:  the flag of item is deleted by self
126  * KV_UPDATE_FLAG:  the flag of item is deleted by update
127  *
128  */
129 #define KV_STATE_OFFSET  1
130 #define KV_ALIGN_MASK   ~(sizeof(void *) - 1)
131 #define KV_DELETE_FLAG   0
132 #define KV_UPDATE_FLAG   1
133 
134 /**
135  * Garbage collection related defination
136  *
137  * KV_RESERVED_BLOCKS: the reserved block for garbage collection
138  *
139  */
140 #define KV_RESERVED_BLOCKS 1
141 
142 /**
143  * Key-value item descriptor defination
144  *
145  * hdr:     the header of the item
146  * store:   the store buffer for key-value pair
147  * len:     the length of the buffer
148  * pos:     the store position of the key-value item
149  *
150  */
151 typedef struct _kv_item_t {
152     item_hdr_t  hdr;
153     char       *store;
154     uint16_t    len;
155     kv_size_t   pos;
156 } kv_item_t;
157 
158 /**
159  * Block information struct for management
160  *
161  * space:   free space in current block
162  * state:   the state of current block
163  *
164  */
165 typedef struct _block_info_t {
166     kv_size_t space;
167     uint8_t   state;
168 } block_info_t;
169 
170 /**
171  * Key-value module management struct
172  *
173  * inited:          the flag to indicate the module is inited
174  * gc_trigger:      the flag to indicate GC is triggered
175  * gc_waiter:       numbers of the task wait for GC finished
176  * clean_blk_nums:  numbers of the clean block
177  * write_pos:       current write position
178  * block_info[]:    the array to record the block management info
179  *
180  */
181 typedef struct _kv_mgr_t {
182     uint8_t       inited;
183     uint8_t       gc_trigger;
184     uint8_t       gc_waiter;
185     uint8_t       clean_blk_nums;
186     kv_size_t     write_pos;
187     void         *gc_sem;
188     void         *lock;
189     block_info_t  block_info[KV_BLOCK_NUMS];
190 } kv_mgr_t;
191 
192 typedef struct _kv_store_t {
193     char     *p;
194     int       res;
195     uint16_t  len;
196 } kv_store_t;
197 
198 /**
199  * Magic Number for block & item
200  */
201 static const uint8_t KV_BLOCK_MAGIC_NUM = 'K';
202 static const uint8_t KV_ITEM_MAGIC_NUM  = 'I';
203 
204 /**
205  * The function to be invoked while polling the used block
206  */
207 typedef int32_t (*item_func)(kv_item_t *item, const char *key);
208 
209 #define KV_ALIGN(x) ((x + ~KV_ALIGN_MASK) & KV_ALIGN_MASK)
210 
211 #endif  /* KV_INTERNAL_H */
212 
213