-
Notifications
You must be signed in to change notification settings - Fork 0
/
Trie.h
182 lines (162 loc) · 4.41 KB
/
Trie.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
#ifndef __TRIE_H__
#define __TRIE_H__
#include <vector>
#include <map>
#include <cstdint>
#include <iterator>
#include <deque>
#include "struct.h"
struct trie_node
{
std::map<uint8_t, trie_node*> children;
trie_node* parent;
std::deque<int32_t> offsets;
int32_t length;
trie_node()
{
length = 0;
parent = nullptr;
}
};
class Trie
{
public:
typedef std::vector<uint8_t>::iterator iterator;
Trie();
Trie(int iMIN_MATCH);
~Trie();
void clear();
/*
@parms
offset - the beginning of the data to compress buffer
cur_pos - current position in data to comressed
la_buffer_end - end of the lookahead buffer
data_end - end of the data to compress buffer
*/
length_offset slide_and_search(uint8_t* data_begin, uint8_t* begin, uint8_t* la_buffer_end, uint8_t* data_end);
void set_minimum_match(int32_t iMIN_MATCH);
void set_sliding_window(int32_t iSlidingWindow);
//Insert operations
template<class InputIterator>
bool insert(int32_t offset, InputIterator begin, InputIterator end);
bool insert(int32_t offset, std::vector<uint8_t> vec)
{
return insert(offset, vec.begin(), vec.end());
}
bool insert(int32_t offset, uint8_t* pointer, uint32_t length)
{
return insert(offset, pointer, pointer + length);
}
//end insert operations
//Delete operations
template<class InputIterator>
void erase(InputIterator begin, InputIterator end);
void erase(std::vector<uint8_t> vec)
{
return erase(vec.begin(), vec.end());
}
void erase(uint8_t* pointer, uint32_t length)
{
return erase(pointer, pointer + length);
}
//end delete operations
//Find operations
template<class InputIterator>
trie_node* find(InputIterator begin, InputIterator end);
trie_node* find(std::vector<uint8_t> vec)
{
return find(vec.begin(), vec.end());
}
trie_node* find(uint8_t* pointer, uint32_t length)
{
return find(pointer, pointer + length);
}
//end fine operations
private:
void clear_helper(trie_node* node);
template<class InputIterator>
trie_node* find_helper(trie_node* node, InputIterator begin, InputIterator end);
template<class InputIterator>
trie_node* insert_helper(trie_node* node, int32_t offset, InputIterator begin, InputIterator end);
template<class InputIterator>
bool erase_helper(trie_node* node, InputIterator begin, InputIterator end);
private:
trie_node* root; //Root node also acts as not found indicator
int32_t m_iMIN_MATCH;
int32_t m_iSlidingWindow;
};
template<class InputIterator>
trie_node* Trie::find_helper(trie_node* node, InputIterator begin, InputIterator end)
{
if(begin >= end)
return node;
std::map<uint8_t, trie_node*>::const_iterator iter = node->children.find(*begin);
if(iter == node->children.end())
return node;
else
return find_helper(iter->second, begin + 1, end);
}
template<class InputIterator>
trie_node* Trie::find(InputIterator begin, InputIterator end)
{
return find_helper(root, begin, end);
}
template<class InputIterator>
trie_node* Trie::insert_helper(trie_node* node, int32_t offset, InputIterator begin, InputIterator end)
{
node->offsets.push_back(offset);
if(begin < end)
{
trie_node* cur_node;
std::map<uint8_t, trie_node*>::iterator iter = node->children.lower_bound(*begin);
if(iter != node->children.end() && !node->children.key_comp()(*begin, iter->first))//Found the node
{
cur_node = iter->second;
}
else
{
cur_node = new trie_node();
cur_node->length = node->length + 1;
cur_node->parent = node;
node->children.insert(iter, std::map<uint8_t, trie_node*>::value_type(*begin, cur_node));
}
return insert_helper(cur_node, offset, begin + 1, end);
}
return node;
}
template<class InputIterator>
bool Trie::insert(int32_t offset, InputIterator begin, InputIterator end)
{
insert_helper(root, offset, begin, end);
return true;
}
template<class InputIterator>
bool Trie::erase_helper(trie_node* node, InputIterator begin, InputIterator end)
{
if(begin < end)
{
std::map<uint8_t, trie_node*>::iterator iter = node->children.find(*begin);
if(iter != node->children.end())
{
bool can_remove = erase_helper(iter->second, begin + 1, end);
if(can_remove)
{
node->children.erase(iter);
}
}
}
node->offsets.pop_front();
if(node->offsets.empty() && node->children.empty())
{
delete node;//At this point the node should not have any children
return true;
}
else
return false;
}
template<class InputIterator>
void Trie::erase(InputIterator begin, InputIterator end)
{
erase_helper(root, begin, end);
}
#endif