forked from wcatykid/Graph-Based-Molecular-Synthesis
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLevelHashMap.h
159 lines (127 loc) · 4.24 KB
/
LevelHashMap.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
/*
* This file is part of esynth.
*
* esynth is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* esynth is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with esynth. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _LEVEL_HASH_MAP_GUARD
#define _LEVEL_HASH_MAP_GUARD 1
#include <utility>
#include <map>
#include "LikeMoleculesContainer.h"
class LevelHashMap
{
private:
LikeMoleculesContainer** like_molecules;
static const unsigned int SIZE = 10000;
unsigned int sz;
// Trusted hash function for strings (found online)
unsigned int hash(char* str) const
{
unsigned long hash = 5381;
int c;
while (c = *str++)
{
hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
}
return hash % SIZE;
}
//
// Handle collisions with linear probing
//
std::pair<unsigned int, bool> privateAdd(MinimalMolecule* const that)
{
unsigned int hashVal = hash(that->key);
// std::cerr << "Hash: " << hashVal << std::endl;
// Add to the table directly or seek the next list.
for (int index = 0; index < SIZE; index++)
{
//
// Does this list exist?
// If not, create the list, add the molecule, and indicate we added successfully.
//
unsigned int properIndex = (index + hashVal) % SIZE;
if (like_molecules[properIndex] == 0)
{
like_molecules[properIndex] = new LikeMoleculesContainer();
like_molecules[properIndex]->add(that);
return std::make_pair(-1, true);
}
// The list exists, inquire if the key matches our key.
if (like_molecules[properIndex]->definesKey(that->key))
{
//
// Determine if this molecule is in the list; if it is, don't add.
//
MinimalMolecule* mol = like_molecules[properIndex]->contains(that);
if (mol) return std::make_pair(mol->uniqueIndexID, false);
// Add to the list with success.
like_molecules[properIndex]->add(that);
return std::make_pair(-1, true);
}
}
return std::make_pair(-1, false);
}
public:
LevelHashMap() : sz(0)
{
like_molecules = new LikeMoleculesContainer*[SIZE];
for (int i = 0; i < SIZE; i++)
{
like_molecules[i] = 0;
}
}
//
// Delete all entries
//
~LevelHashMap()
{
for (int i = 0; i < SIZE; i++)
{
if (like_molecules[i]) delete like_molecules[i];
}
delete[] like_molecules;
}
unsigned int size() const { return sz; }
std::pair<unsigned int, bool> add(MinimalMolecule* const that)
{
std::pair<unsigned int, bool> added = privateAdd(that);
if (added.second) sz++;
return added;
}
//
// This function is provided ONLY for debugging purposes.
// This should NOT be called at all to prevent duplicate isomorphism checks.
//
bool contains(MinimalMolecule* const that) const
{
unsigned int hashVal = hash(that->key);
// Probe linearly.
for (int index = 0; index < SIZE; index++)
{
//
// Does this list exist?
// If not, we don't have containment.
//
unsigned int properIndex = (index + hashVal) % SIZE;
if (like_molecules[properIndex] == 0) return false;
// The list exists, inquire if the key matches our key.
if (like_molecules[properIndex]->definesKey(that->key))
{
return like_molecules[properIndex]->contains(that);
}
}
return false;
}
};
#endif