inital commit
[c11concurrency-benchmarks.git] / mabain / src / mbt_base.cpp
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 #include "mbt_base.h"
20
21 namespace mabain {
22
23 DBTraverseBase::DBTraverseBase(const DB &db) : db_ref(db), rw_buffer(NULL)
24 {
25     if(!(db.GetDBOptions() & CONSTS::ACCESS_MODE_WRITER))
26         throw (int) MBError::NOT_ALLOWED;
27
28     dict = db_ref.GetDictPtr();
29     if(dict == NULL)
30         throw (int) MBError::NOT_INITIALIZED;
31
32     dmm = dict->GetMM();
33     if(dmm == NULL)
34         throw (int) MBError::NOT_INITIALIZED;
35
36     header = dict->GetHeaderPtr();
37     if(header == NULL)
38         throw (int) MBError::NOT_INITIALIZED;
39
40     index_free_lists = dmm->GetFreeList();
41     if(index_free_lists == NULL)
42         throw (int) MBError::NOT_INITIALIZED;
43
44     data_free_lists = dict->GetFreeList();
45     if(data_free_lists == NULL)
46         throw (int) MBError::NOT_INITIALIZED;
47
48     lfree = dict->GetLockFreePtr();
49     if(lfree == NULL)
50         throw (int) MBError::NOT_INITIALIZED;
51
52     rw_buffer_size = 1024;
53     rw_buffer = new uint8_t[rw_buffer_size];
54 }
55
56 DBTraverseBase::~DBTraverseBase()
57 {
58     if(rw_buffer != NULL)
59         delete [] rw_buffer;
60 }
61
62 void DBTraverseBase::TraverseDB(int arg)
63 {
64     DB::iterator iter = DB::iterator(db_ref, DB_ITER_STATE_INIT);
65     int rval = iter.init_no_next();
66     if(rval != MBError::SUCCESS)
67         throw rval;
68
69     DBTraverseNode dbt_node;
70     index_size = dmm->GetRootOffset() + dmm->GetNodeSizePtr()[NUM_ALPHABET-1];
71     data_size = dict->GetStartDataOffset();
72     while(iter.next_dbt_buffer(&dbt_node))
73     {
74         GetAlignmentSize(dbt_node);
75
76         // Run-time determination
77         DoTask(arg, dbt_node);
78
79         if(dbt_node.buffer_type & BUFFER_TYPE_NODE)
80         {
81             iter.add_node_offset(dbt_node.node_offset);
82         }
83     }
84 }
85
86 void DBTraverseBase::GetAlignmentSize(DBTraverseNode &dbt_node) const
87 {
88     if(dbt_node.buffer_type & BUFFER_TYPE_EDGE_STR)
89         dbt_node.edgestr_size = index_free_lists->GetAlignmentSize(dbt_node.edgestr_size);
90
91     if(dbt_node.buffer_type & BUFFER_TYPE_NODE)
92         dbt_node.node_size = index_free_lists->GetAlignmentSize(dbt_node.node_size);
93
94     if(dbt_node.buffer_type & BUFFER_TYPE_DATA)
95     {
96         uint16_t data_size[2];
97         if(dict->ReadData((uint8_t *)&data_size[0], DATA_HDR_BYTE, dbt_node.data_offset)
98                  != DATA_HDR_BYTE)
99             throw (int) MBError::READ_ERROR;
100         dbt_node.data_size = data_free_lists->GetAlignmentSize(data_size[0] + DATA_HDR_BYTE);
101     }
102 }
103
104 void DBTraverseBase::BufferCopy(size_t offset_dst, uint8_t *ptr_dst,
105                                 size_t offset_src, const uint8_t *ptr_src,
106                                 int size, DRMBase *drm)
107 {
108     if(ptr_src != NULL)
109     {
110         if(ptr_dst != NULL)
111         {
112             memcpy(ptr_dst, ptr_src, size);
113         }
114         else
115         {
116             drm->WriteData(ptr_src, size, offset_dst);
117         }
118     }
119     else
120     {
121         if(size > rw_buffer_size)
122             ResizeRWBuffer(size);
123         if(drm->ReadData(rw_buffer, size, offset_src) != size)
124             throw (int) MBError::READ_ERROR;
125
126         if(ptr_dst != NULL)
127         {
128             memcpy(ptr_dst, rw_buffer, size);
129         }
130         else
131         {
132             drm->WriteData(rw_buffer, size, offset_dst);
133         }
134     }
135 }
136
137 void DBTraverseBase::ResizeRWBuffer(int size)
138 {
139     if(rw_buffer != NULL)
140         delete [] rw_buffer;
141     rw_buffer = new uint8_t[size];
142     rw_buffer_size = size;
143 }
144
145 }