Skip to content
This repository was archived by the owner on Aug 10, 2025. It is now read-only.

Commit 3c10031

Browse files
committed
hybrid index initial commit
1 parent 977dbe1 commit 3c10031

26 files changed

+17914
-2
lines changed

src/ee/indexes/BinaryTreeUniqueIndex.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,7 @@ class BinaryTreeUniqueIndex : public TableIndex
271271
m_begin(true),
272272
m_eq(m_keySchema)
273273
{
274+
std::cout << "Binary Unique\n";
274275
m_match = TableTuple(m_tupleSchema);
275276
m_allocator = new AllocatorType(&m_memoryEstimate);
276277
m_entries = new MapType(KeyComparator(m_keySchema), (*m_allocator));

src/ee/indexes/HybridMultiIndex.h

Lines changed: 320 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,320 @@
1+
/* This file is part of VoltDB.
2+
* Copyright (C) 2008-2010 VoltDB Inc.
3+
*
4+
* This file contains original code and/or modifications of original code.
5+
* Any modifications made by VoltDB Inc. are licensed under the following
6+
* terms and conditions:
7+
*
8+
* VoltDB is free software: you can redistribute it and/or modify
9+
* it under the terms of the GNU General Public License as published by
10+
* the Free Software Foundation, either version 3 of the License, or
11+
* (at your option) any later version.
12+
*
13+
* VoltDB is distributed in the hope that it will be useful,
14+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+
* GNU General Public License for more details.
17+
*
18+
* You should have received a copy of the GNU General Public License
19+
* along with VoltDB. If not, see <http://www.gnu.org/licenses/>.
20+
*/
21+
/* Copyright (C) 2008 by H-Store Project
22+
* Brown University
23+
* Massachusetts Institute of Technology
24+
* Yale University
25+
*
26+
* Permission is hereby granted, free of charge, to any person obtaining
27+
* a copy of this software and associated documentation files (the
28+
* "Software"), to deal in the Software without restriction, including
29+
* without limitation the rights to use, copy, modify, merge, publish,
30+
* distribute, sublicense, and/or sell copies of the Software, and to
31+
* permit persons to whom the Software is furnished to do so, subject to
32+
* the following conditions:
33+
*
34+
* The above copyright notice and this permission notice shall be
35+
* included in all copies or substantial portions of the Software.
36+
*
37+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
38+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
39+
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
40+
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
41+
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
42+
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
43+
* OTHER DEALINGS IN THE SOFTWARE.
44+
*/
45+
46+
#ifndef BINARYTREEMULTIMAPINDEX_H_
47+
#define BINARYTREEMULTIMAPINDEX_H_
48+
49+
#include <map>
50+
#include <iostream>
51+
#include "indexes/tableindex.h"
52+
#include "common/tabletuple.h"
53+
#include "stx-compact-multi/btree_multimap.h"
54+
#include "stx-compact-multi/btree.h"
55+
56+
namespace voltdb {
57+
58+
/**
59+
* Index implemented as a Binary Tree Multimap.
60+
* @see TableIndex
61+
*/
62+
template<typename KeyType, class KeyComparator, class KeyEqualityChecker>
63+
class BinaryTreeMultiMapIndex : public TableIndex
64+
{
65+
66+
67+
friend class TableIndexFactory;
68+
69+
//typedef std::multimap<KeyType, const void*, KeyComparator> MapType;
70+
typedef h_index::AllocatorTracker<pair<const KeyType, const void*> > AllocatorType;
71+
//typedef std::multimap<KeyType, const void*, KeyComparator, AllocatorType> MapType;
72+
typedef stx_hybrid_compact_multi::btree_multimap<KeyType, const void*, KeyComparator, stx_hybrid_compact_multi::btree_default_map_traits<KeyType, const void*>, AllocatorType> MapType;
73+
typedef typename MapType::hybrid_iterator MMIter;
74+
75+
public:
76+
77+
~BinaryTreeMultiMapIndex() {
78+
delete m_entries;
79+
delete m_allocator;
80+
};
81+
82+
bool addEntry(const TableTuple *tuple)
83+
{
84+
m_tmp1.setFromTuple(tuple, column_indices_, m_keySchema);
85+
return addEntryPrivate(tuple, m_tmp1);
86+
}
87+
88+
bool deleteEntry(const TableTuple *tuple)
89+
{
90+
m_tmp1.setFromTuple(tuple, column_indices_, m_keySchema);
91+
return deleteEntryPrivate(tuple, m_tmp1);
92+
}
93+
94+
bool replaceEntry(const TableTuple *oldTupleValue,
95+
const TableTuple* newTupleValue)
96+
{
97+
// this can probably be optimized
98+
m_tmp1.setFromTuple(oldTupleValue, column_indices_, m_keySchema);
99+
m_tmp2.setFromTuple(newTupleValue, column_indices_, m_keySchema);
100+
if (m_eq(m_tmp1, m_tmp2))
101+
{
102+
// no update is needed for this index
103+
return true;
104+
}
105+
106+
// It looks like we're deleting the new value and inserting the new value
107+
// The lookup is on the index keys, but the address of the current tuple
108+
// (which has the new key value) is needed for this non-unique index
109+
// to determine which of the tuples with a given key need to be deleted.
110+
bool deleted = deleteEntryPrivate(newTupleValue, m_tmp1);
111+
bool inserted = addEntryPrivate(newTupleValue, m_tmp2);
112+
--m_deletes;
113+
--m_inserts;
114+
++m_updates;
115+
return (deleted && inserted);
116+
}
117+
118+
bool setEntryToNewAddress(const TableTuple *tuple, const void* address, const void *oldAddress) {
119+
m_tmp1.setFromTuple(tuple, column_indices_, m_keySchema);
120+
++m_updates;
121+
122+
// int i = 0;
123+
std::pair<MMIter,MMIter> key_iter;
124+
for (key_iter = m_entries->equal_range_hybrid(m_tmp1);
125+
key_iter.first != key_iter.second;
126+
++(key_iter.first))
127+
{
128+
// VOLT_INFO("iteration %d", i++);
129+
130+
if (key_iter.first->second == oldAddress) {
131+
m_entries->erase_hybrid(key_iter.first);
132+
133+
//std::pair<typename MapType::iterator, bool> retval = m_entries->insert(std::pair<KeyType, const void*>(m_tmp1, address));
134+
//return retval.second;
135+
136+
m_entries->insert(std::pair<KeyType, const void*>(m_tmp1, address));
137+
return true;
138+
}
139+
}
140+
141+
VOLT_INFO("Tuple not found.");
142+
143+
// return true;
144+
145+
//key exists, but not this tuple
146+
return false;
147+
}
148+
149+
bool checkForIndexChange(const TableTuple *lhs, const TableTuple *rhs)
150+
{
151+
m_tmp1.setFromTuple(lhs, column_indices_, m_keySchema);
152+
m_tmp2.setFromTuple(rhs, column_indices_, m_keySchema);
153+
return !(m_eq(m_tmp1, m_tmp2));
154+
}
155+
156+
bool exists(const TableTuple* values)
157+
{
158+
++m_lookups;
159+
m_tmp1.setFromTuple(values, column_indices_, m_keySchema);
160+
return (!m_entries->find_hybrid(m_tmp1).isEnd());
161+
}
162+
163+
bool moveToKey(const TableTuple *searchKey)
164+
{
165+
m_tmp1.setFromKey(searchKey);
166+
return moveToKey(m_tmp1);
167+
}
168+
169+
bool moveToTuple(const TableTuple *searchTuple)
170+
{
171+
m_tmp1.setFromTuple(searchTuple, column_indices_, m_keySchema);
172+
return moveToKey(m_tmp1);
173+
}
174+
175+
void moveToKeyOrGreater(const TableTuple *searchKey)
176+
{
177+
++m_lookups;
178+
m_begin = true;
179+
m_tmp1.setFromKey(searchKey);
180+
m_seqIter = m_entries->lower_bound_hybrid(m_tmp1);
181+
}
182+
183+
void moveToGreaterThanKey(const TableTuple *searchKey)
184+
{
185+
++m_lookups;
186+
m_begin = true;
187+
m_tmp1.setFromKey(searchKey);
188+
m_seqIter = m_entries->upper_bound_hybrid(m_tmp1);
189+
}
190+
191+
void moveToEnd(bool begin)
192+
{
193+
++m_lookups;
194+
//m_begin = begin;
195+
//if (begin)
196+
m_seqIter = m_entries->hybrid_begin();
197+
++m_seqIter;
198+
//else
199+
//m_seqRIter = m_entries->rbegin();
200+
}
201+
202+
TableTuple nextValue()
203+
{
204+
TableTuple retval(m_tupleSchema);
205+
206+
//if (m_begin) {
207+
if (m_seqIter.isEnd())
208+
return TableTuple();
209+
retval.move(const_cast<void*>(m_seqIter->second));
210+
if (!m_seqIter.isComplete())
211+
m_seqIter = m_entries->lower_bound_hybrid(m_seqIter->first);
212+
++m_seqIter;
213+
/*
214+
} else {
215+
if (m_seqRIter == (typename MapType::const_reverse_iterator) m_entries->rend())
216+
return TableTuple();
217+
retval.move(const_cast<void*>(m_seqRIter->second));
218+
++m_seqRIter;
219+
}
220+
*/
221+
return retval;
222+
}
223+
224+
TableTuple nextValueAtKey()
225+
{
226+
if (m_match.isNullTuple()) return m_match;
227+
TableTuple retval = m_match;
228+
++(m_keyIter.first);
229+
if (m_keyIter.first == m_keyIter.second)
230+
m_match.move(NULL);
231+
else
232+
m_match.move(const_cast<void*>(m_keyIter.first->second));
233+
return retval;
234+
}
235+
236+
bool advanceToNextKey()
237+
{
238+
if (m_keyIter.second.isEnd())
239+
return false;
240+
return moveToKey(m_keyIter.second->first);
241+
}
242+
243+
size_t getSize() const { return m_entries->size(); }
244+
245+
int64_t getMemoryEstimate() const {
246+
return m_memoryEstimate + m_entries->get_static_data_size() + m_entries->get_bloom_filter_size();
247+
}
248+
249+
std::string getTypeName() const { return "BinaryTreeMultiMapIndex"; };
250+
251+
protected:
252+
BinaryTreeMultiMapIndex(const TableIndexScheme &scheme) :
253+
TableIndex(scheme),
254+
m_begin(true),
255+
m_eq(m_keySchema)
256+
{
257+
m_match = TableTuple(m_tupleSchema);
258+
m_allocator = new AllocatorType(&m_memoryEstimate);
259+
m_entries = new MapType(KeyComparator(m_keySchema), (*m_allocator));
260+
}
261+
262+
inline bool addEntryPrivate(const TableTuple *tuple, const KeyType &key)
263+
{
264+
++m_inserts;
265+
m_entries->insert(key, tuple->address());
266+
return true;
267+
}
268+
269+
inline bool deleteEntryPrivate(const TableTuple *tuple, const KeyType &key)
270+
{
271+
++m_deletes;
272+
std::pair<MMIter,MMIter> key_iter;
273+
for (key_iter = m_entries->equal_range_hybrid(key);
274+
key_iter.first != key_iter.second;
275+
++(key_iter.first))
276+
{
277+
if (key_iter.first->second == tuple->address())
278+
{
279+
m_entries->erase_hybrid(key_iter.first);
280+
//deleted
281+
return true;
282+
}
283+
}
284+
//key exists, but tuple not exists
285+
return false;
286+
}
287+
288+
bool moveToKey(const KeyType &key)
289+
{
290+
++m_lookups;
291+
m_begin = true;
292+
m_keyIter = m_entries->equal_range_hybrid(key);
293+
if (m_keyIter.first == m_keyIter.second)
294+
{
295+
m_match.move(NULL);
296+
return false;
297+
}
298+
m_match.move(const_cast<void*>(m_keyIter.first->second));
299+
return !m_match.isNullTuple();
300+
}
301+
302+
MapType *m_entries;
303+
AllocatorType *m_allocator;
304+
KeyType m_tmp1;
305+
KeyType m_tmp2;
306+
307+
// iteration stuff
308+
bool m_begin;
309+
typename std::pair<MMIter, MMIter> m_keyIter;
310+
MMIter m_seqIter;
311+
//MMCRIter m_seqRIter;
312+
TableTuple m_match;
313+
314+
// comparison stuff
315+
KeyEqualityChecker m_eq;
316+
};
317+
318+
}
319+
320+
#endif // BINARYTREEMULTIMAPINDEX_H_

0 commit comments

Comments
 (0)