remove conflict
[c11concurrency-benchmarks.git] / mabain / src / db.h
1 /**
2  * Copyright (C) 2017 Cisco Inc.
3  *
4  * This program is free software: you can redistribute it and/or  modify
5  * it under the terms of the GNU General Public License, version 2,
6  * as published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
15  */
16
17 // @author Changxue Deng <chadeng@cisco.com>
18
19 #ifndef __DB_H__
20 #define __DB_H__
21
22 #include <iostream>
23 #include <string>
24
25 #include "mb_data.h"
26 #include "error.h"
27 #include "lock.h"
28 #include "integer_4b_5b.h"
29
30 namespace mabain {
31
32
33 #define MB_MAX_NUM_SHM_QUEUE_NODE  64
34
35 class Dict;
36 class MBlsq;
37 class LockFree;
38 class AsyncWriter;
39 struct _DBTraverseNode;
40
41 typedef struct _MBConfig
42 {
43     const char *mbdir;
44     int options;
45     size_t memcap_index;
46     size_t memcap_data;
47     int data_size;    
48     uint32_t connect_id;
49     uint32_t block_size_index;
50     uint32_t block_size_data;
51     int max_num_data_block;
52     int max_num_index_block;
53
54     // For automatic eviction
55     // All entries in the oldest buckets will be pruned.
56     int num_entry_per_bucket;
57     uint32_t queue_size;
58 } MBConfig;
59
60 // Database handle class
61 class DB
62 {
63 public:
64     // DB iterator class as an inner class
65     class iterator
66     {
67     friend class DBTraverseBase;
68
69     public:
70         std::string key;
71         MBData value;
72         int match;
73
74         iterator(const DB &db, int iter_state);
75         // Copy constructor
76         iterator(const iterator &rhs);
77         void init(bool check_async_mode = true);
78         int init_no_next();
79         ~iterator();
80
81         // operator overloading
82         bool operator!=(const iterator &rhs);
83         const iterator& operator++();
84
85     private:
86         int  get_node_offset(const std::string &node_key, size_t &parent_edge_off,
87                  size_t &node_offset);
88         int  load_node(const std::string &curr_node_key, size_t &parent_edge_off);
89         int  load_kv_for_node(const std::string &curr_node_key);
90         int  load_kvs(const std::string &curr_node_key, MBlsq *chid_node_list);
91         void iter_obj_init();
92         bool next_dbt_buffer(struct _DBTraverseNode *dbt_n);
93         void add_node_offset(size_t node_offset);
94         iterator* next();
95
96         const DB &db_ref;
97         int state;
98         EdgePtrs edge_ptrs;
99         // temp buffer to hold the node
100         uint8_t node_buff[NUM_ALPHABET+NODE_EDGE_KEY_FIRST];
101         MBlsq *node_stack;
102         MBlsq *kv_per_node;
103         LockFree *lfree;
104     };
105
106     // db_path: database directory
107     // db_options: db access option (read/write)
108     // memcap_index: maximum memory size in bytes for key index
109     // memcap_data: maximum memory size for data file mapping
110     // data_size: the value size; if zero, the value size will be variable.
111     // id: the connector id
112     DB(const char *db_path, int db_options, size_t memcap_index = 64*1024*1024LL,
113        size_t memcap_data = 64*1024*1024LL, uint32_t id = 0, uint32_t queue_size = MB_MAX_NUM_SHM_QUEUE_NODE);
114     DB(MBConfig &config);
115     ~DB();
116
117     DB(const DB &db);
118     const DB& operator = (const DB &db);
119
120     // Add a key-value pair
121     int Add(const char* key, int len, const char* data, int data_len, bool overwrite = false);
122     int Add(const char* key, int len, MBData &data, bool overwrite = false);
123     int Add(const std::string &key, const std::string &value, bool overwrite = false);
124     // Find an entry by exact match using a key
125     int Find(const char* key, int len, MBData &mdata) const;
126     int Find(const std::string &key, MBData &mdata) const;
127     // Find all possible prefix matches using a key
128     // This is not fully implemented yet.
129     int FindPrefix(const char* key, int len, MBData &data) const;
130     // Find the longest prefix match using a key
131     int FindLongestPrefix(const char* key, int len, MBData &data) const;
132     int FindLongestPrefix(const std::string &key, MBData &data) const;
133     // Remove an entry using a key
134     int Remove(const char *key, int len);
135     int Remove(const std::string &key);
136     int RemoveAll();
137     // DB Backup
138     int Backup(const char *backup_dir);
139
140     // Close the DB handle
141     int  Close();
142     void Flush() const;
143     static void ClearResources(const std::string &path);
144
145     // Garbage collection
146     // min_index_rc_size and min_data_rc_size are the threshold for trigering garbage
147     // collector. If the pending index buffer size is less than min_index_rc_size,
148     // rc will be ignored for index segment. If the pending data buffer size is less
149     // than min_data_rc_size, rc will be ignored for data segment.
150     // eviction will be ignored if db size is less than 0xFFFFFFFFFFFF and db count is
151     // less than 0xFFFFFFFFFFFF.
152     int CollectResource(int64_t min_index_rc_size = 33554432 , int64_t min_data_rc_size = 33554432,
153                         int64_t max_dbsiz = MAX_6B_OFFSET, int64_t max_dbcnt = MAX_6B_OFFSET);
154
155     // Multi-thread update using async thread
156     // FOR THIS TO WORK, WRITER MUST BE THE LAST ONE TO CLOSE HANDLE.
157     int  SetAsyncWriterPtr(DB *db_writer);
158     int  UnsetAsyncWriterPtr(DB *db_writer);
159     bool AsyncWriterEnabled() const;
160     bool AsyncWriterBusy() const;
161
162     // multi-thread or multi-process locking for DB management
163     int WrLock();
164     int RdLock();
165     int UnLock();
166     int TryWrLock();
167     int ClearLock() const;
168
169     int UpdateNumHandlers(int mode, int delta);
170
171     // level 0: only error will be logged.
172     // level 1: error and warn will be logged.
173     // level 2: error, warn, and info will be logged. This is the default setting.
174     // level 3: error, warn, info and debug will be logged.
175     static void SetLogFile(const std::string &log_file);
176     static int  SetLogLevel(int level);
177     static void LogDebug();
178     static void CloseLogFile();
179
180     // Print database stats
181     void PrintStats(std::ostream &out_stream = std::cout) const;
182     void PrintHeader(std::ostream &out_stream = std::cout) const;
183     // current count of key-value pair
184     int64_t Count() const;
185     // DB status
186     int Status() const;
187     // DB status string
188     const char *StatusStr() const;
189     // Check if DB is opened successfully
190     bool is_open() const;
191
192     Dict* GetDictPtr() const;
193     int   GetDBOptions() const;
194     const std::string& GetDBDir() const;
195
196     void GetDBConfig(MBConfig &config) const;
197
198     //iterator
199     const iterator begin(bool check_async_mode = true, bool rc_mode = false) const;
200     const iterator end() const;
201
202 private:
203     void InitDB(MBConfig &config);
204     void PreCheckDB(const MBConfig &config, bool &init_header, bool &update_header);
205     void PostDBUpdate(const MBConfig &config, bool init_header, bool update_header);
206     static int ValidateConfig(MBConfig &config);
207
208     // DB directory
209     std::string mb_dir;
210     int options;
211     Dict *dict;
212     int status;
213
214     // DB connector ID
215     uint32_t identifier;
216
217     // db lock
218     MBLock lock;
219     MBConfig dbConfig;
220
221     AsyncWriter *async_writer;
222
223     int writer_lock_fd;
224 };
225
226 }
227
228 #endif