-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathlightkv.h
151 lines (113 loc) · 3.67 KB
/
lightkv.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#ifndef LIGHTKV_H
#define LIGHTKV_H 1
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
#define MAX_NFILES 50
#define MAX_SIZES 20
#define FIRST_SIZECLASS 3
#define MAX_RECORD_SIZE 33554432
#define MAX_FILESIZE 1073741824
#define RECORD_HEADER_SIZE 8
#define RECORD_NULL 0
#define RECORD_VAL 1
#define RECORD_DEL 2
#define RECODE_END 3
// Use mmaping
//#define USE_MMAP 1
#ifdef __cplusplus
extern "C" {
#endif
// Data record
typedef struct __attribute__((__packed__)) {
// header starts
uint8_t type; // type of record
uint8_t extlen; // extra length - key size
uint16_t seqno; // future journaling stuff
uint32_t len; // total size of record
// header ends
} record;
// Location
typedef union {
struct __attribute__((__packed__)) {
uint16_t num; // File number
uint16_t sclass; // Size class
uint32_t offset; // Offset within file
} l;
uint64_t val; // Represent as record id
} loc;
// Data struct to keep size list belonging to a class
// TODO: Replace with a rbtree to ensure O(logn) and improve fragmentation
typedef struct _freeloc {
loc l;
struct _freeloc *prev, *next;
} freeloc;
freeloc *freeloc_new(loc l);
freeloc *freelist_add(freeloc *head, freeloc *n);
freeloc *freelist_get(freeloc *head, uint32_t size);
freeloc *freelist_remove(freeloc *head, freeloc *f);
typedef struct {
uint16_t version; // Lightkv version
const char *basepath; // Base db directory path
#ifdef USE_MMAP
void *filemaps[MAX_NFILES]; // Pointer to file mmaps
#else
int fds[MAX_SIZES];
#endif
uint16_t nfiles; // Currently initialized max files
bool prealloc; // Need pre-file allocation
loc start_loc, end_loc; // Location reference to start and current end
freeloc *freelist[MAX_SIZES]; // Slab allocation list
int error; // err num
bool has_scanned;
} lightkv;
// Create a file with given size and fill zeros
int alloc_file(const char *filepath, size_t size);
// Memory map an existing file
int map_file(void **map, const char *filepath);
// Allocate the next location
loc create_nextloc(lightkv *kv, uint32_t size);
// Write record into disk
int write_record(lightkv *kv, loc l, record *rec);
// Read record from a location
int read_record(lightkv *kv, loc l, record **rec);
// Read record header from a location
record read_recheader(lightkv *kv, loc l);
// Create a record
record *create_record(uint8_t type, const char *key, const char *val, size_t len, size_t recsize);
// Find or create a free loc to store record of given size
loc find_freeloc(lightkv *kv, size_t size);
// Public methods
// Initialize db
int lightkv_init(lightkv **kv, const char *base, bool prealloc);
// Has error occured?
bool lightkv_has_error(lightkv *kv);
// Get error string
char *lightkv_errorstr(lightkv *kv);
// Insert
uint64_t lightkv_insert(lightkv *kv, const char *key, const char *val, uint32_t len);
// Update
uint64_t lightkv_update(lightkv *kv, uint64_t recid, const char *key, const char *val, uint32_t len);
// Delete
bool lightkv_delete(lightkv *kv, uint64_t recid);
// Get
bool lightkv_get(lightkv *kv, uint64_t recid, char **key, char **val, uint32_t *len);
// Lightkv iterator object
typedef struct {
lightkv *store;
loc current;
} lightkv_iter;
// Scan whole db
lightkv_iter *lightkv_iterator(lightkv *kv);
// Get next item
bool lightkv_next(lightkv_iter *iter, uint64_t *recid, char **key, char **val, uint32_t *len);
// Free iterator
void lightkv_free_iter(lightkv_iter *iter);
// Fsync
void lightkv_sync(lightkv *kv);
// Cleanup and close
void lightkv_close(lightkv *kv);
#ifdef __cplusplus
}
#endif
#endif