2 * Copyright (C) 2017 Cisco Inc.
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.
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.
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/>.
17 // @author Changxue Deng <chadeng@cisco.com>
23 DBTraverseBase::DBTraverseBase(const DB &db) : db_ref(db), rw_buffer(NULL)
25 if(!(db.GetDBOptions() & CONSTS::ACCESS_MODE_WRITER))
26 throw (int) MBError::NOT_ALLOWED;
28 dict = db_ref.GetDictPtr();
30 throw (int) MBError::NOT_INITIALIZED;
34 throw (int) MBError::NOT_INITIALIZED;
36 header = dict->GetHeaderPtr();
38 throw (int) MBError::NOT_INITIALIZED;
40 index_free_lists = dmm->GetFreeList();
41 if(index_free_lists == NULL)
42 throw (int) MBError::NOT_INITIALIZED;
44 data_free_lists = dict->GetFreeList();
45 if(data_free_lists == NULL)
46 throw (int) MBError::NOT_INITIALIZED;
48 lfree = dict->GetLockFreePtr();
50 throw (int) MBError::NOT_INITIALIZED;
52 rw_buffer_size = 1024;
53 rw_buffer = new uint8_t[rw_buffer_size];
56 DBTraverseBase::~DBTraverseBase()
62 void DBTraverseBase::TraverseDB(int arg)
64 DB::iterator iter = DB::iterator(db_ref, DB_ITER_STATE_INIT);
65 int rval = iter.init_no_next();
66 if(rval != MBError::SUCCESS)
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))
74 GetAlignmentSize(dbt_node);
76 // Run-time determination
77 DoTask(arg, dbt_node);
79 if(dbt_node.buffer_type & BUFFER_TYPE_NODE)
81 iter.add_node_offset(dbt_node.node_offset);
86 void DBTraverseBase::GetAlignmentSize(DBTraverseNode &dbt_node) const
88 if(dbt_node.buffer_type & BUFFER_TYPE_EDGE_STR)
89 dbt_node.edgestr_size = index_free_lists->GetAlignmentSize(dbt_node.edgestr_size);
91 if(dbt_node.buffer_type & BUFFER_TYPE_NODE)
92 dbt_node.node_size = index_free_lists->GetAlignmentSize(dbt_node.node_size);
94 if(dbt_node.buffer_type & BUFFER_TYPE_DATA)
96 uint16_t data_size[2];
97 if(dict->ReadData((uint8_t *)&data_size[0], DATA_HDR_BYTE, dbt_node.data_offset)
99 throw (int) MBError::READ_ERROR;
100 dbt_node.data_size = data_free_lists->GetAlignmentSize(data_size[0] + DATA_HDR_BYTE);
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)
112 memcpy(ptr_dst, ptr_src, size);
116 drm->WriteData(ptr_src, size, offset_dst);
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;
128 memcpy(ptr_dst, rw_buffer, size);
132 drm->WriteData(rw_buffer, size, offset_dst);
137 void DBTraverseBase::ResizeRWBuffer(int size)
139 if(rw_buffer != NULL)
141 rw_buffer = new uint8_t[size];
142 rw_buffer_size = size;