remove conflict
[c11concurrency-benchmarks.git] / mabain / src / drm_base.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 __DRM_BASE_H__
20 #define __DRM_BASE_H__
21
22 #include "rollable_file.h"
23 #include "free_list.h"
24
25 #define DATA_BUFFER_ALIGNMENT      1
26 #define DATA_SIZE_BYTE             2
27 #define DATA_HDR_BYTE              4
28 #define OFFSET_SIZE                6
29 #define EDGE_SIZE                  13
30 #define EDGE_LEN_POS               5
31 #define EDGE_FLAG_POS              6
32 #define EDGE_FLAG_DATA_OFF         0x01
33 #define FLAG_NODE_MATCH            0x01
34 #define FLAG_NODE_NONE             0x0
35 #define BUFFER_ALIGNMENT           1
36 #define LOCAL_EDGE_LEN             6
37 #define LOCAL_EDGE_LEN_M1          5
38 #define EDGE_NODE_LEADING_POS      7
39 #define EXCEP_STATUS_NONE          0
40 #define EXCEP_STATUS_ADD_EDGE      1
41 #define EXCEP_STATUS_ADD_DATA_OFF  2
42 #define EXCEP_STATUS_ADD_NODE      3
43 #define EXCEP_STATUS_REMOVE_EDGE   4
44 #define EXCEP_STATUS_CLEAR_EDGE    5
45 #define EXCEP_STATUS_RC_NODE       6
46 #define EXCEP_STATUS_RC_EDGE_STR   7
47 #define EXCEP_STATUS_RC_DATA       8
48 #define EXCEP_STATUS_RC_TREE       9
49 #define MB_EXCEPTION_BUFF_SIZE     16
50
51 namespace mabain {
52
53 // Mabain DB header
54 typedef struct _IndexHeader
55 {
56     uint16_t version[4];
57     int      data_size;
58     int64_t  count;
59     size_t   m_data_offset;
60     size_t   m_index_offset;
61     int64_t  pending_data_buff_size;
62     int64_t  pending_index_buff_size;
63     int64_t  n_states;
64     int64_t  n_edges;
65     int64_t  edge_str_size;
66     int      num_writer;
67     int      num_reader;
68     std::atomic<size_t> shm_index_sliding_start;
69     std::atomic<size_t> shm_data_sliding_start;
70
71     // Lock-free data structure
72     LockFreeShmData lock_free;
73
74     // read/write lock
75     pthread_rwlock_t mb_rw_lock;
76
77     // block size
78     uint32_t index_block_size;
79     uint32_t data_block_size;
80     // number of entry per bucket for eviction
81     int64_t  entry_per_bucket;
82     // number of DB insertions and updates
83     // used for assigning bucket
84     int64_t  num_update;
85     uint16_t eviction_bucket_index;
86
87     // temp variables used for abnormal writer terminations
88     int     excep_updating_status;
89     uint8_t excep_buff[MB_EXCEPTION_BUFF_SIZE];
90     size_t  excep_offset;
91     size_t  excep_lf_offset;
92
93     // index root offset for insertions during rc
94     size_t               rc_m_index_off_pre;
95     size_t               rc_m_data_off_pre;
96     std::atomic<size_t>  rc_root_offset;
97     int64_t              rc_count;
98
99     // multi-process async queue
100     int                   async_queue_size;
101     std::atomic<uint32_t> queue_index;
102     uint32_t              writer_index;
103     std::atomic<uint32_t> rc_flag;
104 } IndexHeader;
105
106 // An abstract interface class for Dict and DictMem
107 class DRMBase
108 {
109 public:
110     DRMBase()
111     {
112         // Derived classes will initialize these objects.
113         kv_file = NULL;
114         free_lists = NULL;
115     }
116
117     ~DRMBase()
118     {
119     }
120
121     inline virtual void WriteData(const uint8_t *buff, unsigned len, size_t offset) const = 0;
122     inline int Reserve(size_t &offset, int size, uint8_t* &ptr);
123     inline uint8_t* GetShmPtr(size_t offset, int size) const;
124     inline size_t CheckAlignment(size_t offset, int size) const;
125     inline int ReadData(uint8_t *buff, unsigned len, size_t offset) const;
126     inline size_t GetResourceCollectionOffset() const;
127     inline void RemoveUnused(size_t max_size, bool writer_mode = false);
128
129     FreeList *GetFreeList() const
130     {
131         return free_lists;
132     }
133
134     IndexHeader *GetHeaderPtr() const
135     {
136         return header;
137     }
138
139     void PrintHeader(std::ostream &out_stream) const;
140
141     static void ValidateHeaderFile(const std::string &header_path, int mode, int queue_buff_size,
142                                    bool &update_header);
143
144 protected:
145     static void ReadHeaderVersion(const std::string &header_path, uint16_t ver[4]);
146     static void ReadHeader(const std::string &header_path, uint8_t *buff, int buf_size);
147     static void WriteHeader(const std::string &header_path, uint8_t *buff, int queue_buff_size);
148
149     IndexHeader *header;
150     RollableFile *kv_file;
151     FreeList *free_lists;
152 };
153
154 inline void DRMBase::WriteData(const uint8_t *buff, unsigned len, size_t offset) const
155 {
156     if(kv_file->RandomWrite(buff, len, offset) != len)
157         throw (int) MBError::WRITE_ERROR;
158 }
159
160 inline int DRMBase::Reserve(size_t &offset, int size, uint8_t* &ptr)
161 {
162     return kv_file->Reserve(offset, size, ptr);
163 }
164
165 inline uint8_t* DRMBase::GetShmPtr(size_t offset, int size) const
166 {
167     return kv_file->GetShmPtr(offset, size);
168 }
169
170 inline size_t DRMBase::CheckAlignment(size_t offset, int size) const
171 {
172     return kv_file->CheckAlignment(offset, size);
173 }
174
175 inline int DRMBase::ReadData(uint8_t *buff, unsigned len, size_t offset) const
176 {
177     return kv_file->RandomRead(buff, len, offset);
178 }
179
180 inline size_t DRMBase::GetResourceCollectionOffset() const
181 {
182     return kv_file->GetResourceCollectionOffset();
183 }
184
185 inline void DRMBase::RemoveUnused(size_t max_size, bool writer_mode)
186 {
187     return kv_file->RemoveUnused(max_size, writer_mode); 
188 }
189
190 }
191
192 #endif