QNANO
Index_Hash_Table.h
1 #ifndef QNANO_NEW_INDEX_HASH_TABLE_DEFINED_H
2 #define QNANO_NEW_INDEX_HASH_TABLE_DEFINED_H
3 
4 #include <vector>
5 #include <iostream>
6 #include <cstdlib>
7 
8 template <class Key_Type> class Index_Hash_Table_Node {
9 public:
10  Key_Type key;
11  int next;
12 
13  Index_Hash_Table_Node(const Key_Type &key_, int next_=-1) :key(key_), next(next_){
14  }
15 
16 };
17 
18 template <class Key_Type> class Index_Hash_Table {
19 public:
20  std::vector<Index_Hash_Table_Node<Key_Type> > nodes;
21  std::vector<int> start_table;
22 
23  size_t (*hash_fct)(const Key_Type &key);
24 
25  void clear(){
26  nodes.clear();
27  for(size_t i=0; i<start_table.size(); i++)start_table[i]=-1;
28  }
29  size_t size()const{return nodes.size();}
30 
31  inline size_t get_start_index(const Key_Type &key, size_t stsize)const{
32  size_t hash=hash_fct(key);
33  return hash%stsize;
34  }
35  inline size_t get_start_index(const Key_Type &key)const{
36  return get_start_index(key,start_table.size());
37  }
38 
39  int get_index(const Key_Type &key)const{
40  int index=start_table[get_start_index(key)];
41  while(index>=0){
42  if(nodes[index].key==key)return index;
43  index=nodes[index].next;
44  }
45  return -1;
46  }
47  int get_index_check(const Key_Type &key)const{
48  int i=get_index(key);
49  if(i<0){
50  std::cerr<<"Index_Hash_Table::get_index_check: key "<<key<<"not found!"<<std::endl;
51  exit(1);
52  }
53  }
54 
55  const Key_Type & get_key(int index)const{
56  if(index<0 || index >=(int)nodes.size()){
57  std::cerr<<"Index_Hash_Table::get_key: index out of bound: "<<index<<" vs. [0,"<<nodes.size()<<"["<<std::endl;
58  exit(1);
59  }
60  return nodes[index].key;
61  }
62 
63 
64  void resize_start_table(size_t size){
65  start_table.resize(size);
66  for(size_t i=0; i<size; i++){
67  start_table[i]=-1;
68  }
69 
70  for(size_t i=0; i<nodes.size(); i++){
71  nodes[i].next=-1;
72  }
73 
74 
75  for(size_t n=0; n<nodes.size(); n++){
76  size_t start_index=get_start_index(nodes[n].key);
77  int index=start_table[start_index];
78 
79  //need to make an entry in the start_table?
80  if(index<0){
81  start_table[start_index]=n;
82  continue;
83  }
84 
85  while(true){
86  if(nodes[index].key==nodes[n].key)break; //already exists. Don't do anything
87  int next_index=nodes[index].next;
88  if(next_index<0){//reached the end of the linked list: append
89  nodes[index].next=n;
90  break;
91  }
92  index=next_index;
93  }
94  }
95 
96 // std::cout<<"Index_Hash_Table::resize(): -> "<<size<<std::endl;
97  }
98 
99 
100 
101  void add(const Key_Type &key){
102  if(nodes.size()>=1.5*start_table.size())resize_start_table(start_table.size()*2);
103 
104  size_t start_index=get_start_index(key);
105  int index=start_table[start_index];
106 
107  //need to make an entry in the start_table?
108  if(index<0){
109  size_t old_nodes_size=nodes.size();
110  nodes.push_back(Index_Hash_Table_Node<Key_Type>(key));
111  start_table[start_index]=old_nodes_size;
112  return;
113  }
114 
115 
116  while(true){
117  if(nodes[index].key==key)return; //already exists. Don't do anything
118  int next_index=nodes[index].next;
119  if(next_index<0){//reached the end of the linked list: append
120  size_t old_nodes_size=nodes.size();
121  nodes.push_back(Index_Hash_Table_Node<Key_Type>(key));
122  nodes[index].next=old_nodes_size;
123  return;
124  }
125  index=next_index;
126  }
127 
128  }
129 
130  void print_start_table(std::ostream &os=std::cout)const{
131  os<<"Start Table:"<<std::endl;
132  for(size_t i=0; i<start_table.size(); i++){
133  os<<i<<": "<<start_table[i]<<std::endl;
134  }
135  }
136  void print_nodes(std::ostream &os=std::cout)const{
137  os<<"Nodes:"<<std::endl;
138  for(size_t i=0; i<nodes.size(); i++){
139  os<<i<<": "<<nodes[i].key<<": "<<nodes[i].next<<std::endl;
140  }
141  }
142  void print(std::ostream &os=std::cout)const{
143  std::cout<<"start_table.size(): "<<start_table.size()<<std::endl;
144  std::cout<<"nodes.size(): "<<nodes.size()<<std::endl;
145  print_start_table(os);
146  print_nodes(os);
147  }
148 
149 
150  Index_Hash_Table(const Index_Hash_Table &other)
151  : nodes(other.nodes), start_table(other.start_table),
152  hash_fct(other.hash_fct){
153  }
154 
155  Index_Hash_Table(size_t (*hash_fct_)(const Key_Type &), size_t start_table_size=128)
156  : hash_fct(hash_fct_) {
157 
158  start_table.resize(start_table_size);
159  for(size_t i=0; i<start_table_size; i++){
160  start_table[i]=-1;
161  }
162  }
163 
164 
165 };
166 
167 #endif
168 
Definition: Index_Hash_Table.h:18
Definition: Index_Hash_Table.h:8