Skip to content

Commit c3d9142

Browse files
committed
Test application added
1 parent fba0386 commit c3d9142

1 file changed

Lines changed: 319 additions & 0 deletions

File tree

test-app/test-app.cpp

Lines changed: 319 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,319 @@
1+
/*
2+
Spatial Bloom Filter C++ Library (libSBF-cpp)
3+
Copyright (C) 2017 Luca Calderoni, Dario Maio,
4+
University of Bologna
5+
Copyright (C) 2017 Paolo Palmieri,
6+
Cranfield University
7+
8+
This program is free software: you can redistribute it and/or modify
9+
it under the terms of the GNU Lesser 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+
This program 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 Lesser General Public License for more details.
17+
18+
You should have received a copy of the GNU Lesser General Public License
19+
along with this program. If not, see <http://www.gnu.org/licenses/>.
20+
*/
21+
22+
#include <sbflib.h>
23+
24+
#include <ctime>
25+
#include <iostream>
26+
#include <fstream>
27+
#include <sstream>
28+
#include <string>
29+
#include <math.h>
30+
#include <stdlib.h>
31+
32+
33+
//This simple program allows to build a SBF over our test datasets and
34+
//to perform some tests upon it.
35+
//Specifically, the filter is tested with its own elements and with a larger set
36+
//of elements which don't belong to the filter at all.
37+
int main() {
38+
39+
std::ifstream myfile;
40+
std::string line, a, member;
41+
int len, line_count, area, area_check, n, narea, nver;
42+
int well_recognised, false_positives, exchanged_elements;
43+
char* element;
44+
sbf::SBF* myFilter;
45+
46+
/* ****************************** SETTINGS ****************************** */
47+
48+
//csv file delimiter
49+
std::string delimiter = ",";
50+
51+
int perform_verification = 0;
52+
int print_mode = 0;
53+
54+
//desired false positives probability (upper bound)
55+
double max_fpp = 0.001;
56+
57+
//select the construction dataset to be used
58+
std::string construction_dataset;
59+
60+
//select the verification dataset
61+
std::string verification_dataset;
62+
63+
//specify the hash salt data file
64+
time_t timer;
65+
struct tm * timeinfo;
66+
char buffer[80];
67+
time(&timer);
68+
timeinfo = localtime(&timer);
69+
strftime(buffer, sizeof(buffer), "%d-%m-%Y-%I_%M_%S", timeinfo);
70+
std::string buf(buffer);
71+
std::string hash_salt("SBFHashSalt" + buf + ".txt");
72+
73+
74+
//the exponent that determines filter size (in cells)
75+
int bit_mapping;
76+
//the number of hash executions for each mapped element
77+
int hn;
78+
//hash function to be used
79+
int hf = 4;
80+
81+
/* **************************** END SETTINGS **************************** */
82+
83+
84+
//prints licence information
85+
printf("Spatial Bloom Filters\nCopyright (C) 2017 Luca Calderoni, Dario Maio (University of Bologna), Paolo Palmieri (Cranfield University)\nThis program comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome\nto redistribute it under certain conditions.\nSee the attached files 'COPYING' and 'COPYING.LESSER' for details.\n\n");
86+
87+
88+
89+
/* ***************************** USER INPUT ***************************** */
90+
91+
std::string input;
92+
//asks for construction dataset file (mandatory)
93+
std::cout << "Enter the name of the construction dataset (like area-elements-unif.csv)..." << std::endl;
94+
std::cin >> construction_dataset;
95+
std::cin.ignore();
96+
97+
//asks for hash type (optional)
98+
while (true) {
99+
std::cout << "Enter the type of hash function to use:" << std::endl;
100+
std::cout << "1 (SHA1), 4 (MD4), 5(MD5) (press ENTER for default)..." << std::endl;
101+
getline(std::cin, input);
102+
103+
if (input.empty()) break;
104+
else {
105+
std::istringstream istr(input);
106+
istr >> hf;
107+
break;
108+
}
109+
110+
std::cout << "Invalid number, please try again" << std::endl;
111+
}
112+
113+
//asks for hash salt data file (optional)
114+
std::cout << "Enter the name of the hash salt data file (like SBFHashSalt.txt)" << std::endl;
115+
std::cout << "(press ENTER for default)..." << std::endl;
116+
getline(std::cin, input);
117+
118+
if (input.empty()) {
119+
//nothing to do
120+
}
121+
else {
122+
std::istringstream istr(input);
123+
istr >> hash_salt;
124+
}
125+
126+
//asks for verification dataset file (optional)
127+
std::cout << "Enter the name of the verification dataset (like non-elements.csv)" << std::endl;
128+
std::cout << "(press ENTER to ignore)..." << std::endl;
129+
getline(std::cin, input);
130+
131+
if (input.empty()) {
132+
//nothing to do
133+
}
134+
else {
135+
perform_verification = 1;
136+
std::istringstream istr(input);
137+
istr >> verification_dataset;
138+
}
139+
140+
141+
//asks for print mode (optional)
142+
while (true) {
143+
std::cout << "Enter the print mode to use:" << std::endl;
144+
std::cout << "1 (prints filter information to the standard output)" << std::endl;
145+
std::cout << "2 (prints filter information and cells values to the standard output)" << std::endl;
146+
std::cout << "3 (save both filter and related meta data to disk)" << std::endl;
147+
std::cout << "(press ENTER to ignore)..." << std::endl;
148+
getline(std::cin, input);
149+
150+
if (input.empty()) break;
151+
else {
152+
std::istringstream istr(input);
153+
istr >> print_mode;
154+
if (print_mode != 1 && print_mode != 2 && print_mode != 3) print_mode = 0;
155+
break;
156+
}
157+
158+
std::cout << "Invalid number, please try again" << std::endl;
159+
}
160+
161+
/* *************************** END USER INPUT *************************** */
162+
163+
164+
165+
166+
//determines the number of elements and the number of areas depending on the
167+
//chosen dataset
168+
myfile.open(construction_dataset.c_str());
169+
if (myfile.is_open()) {
170+
line_count = 0;
171+
while (getline(myfile, line)) {
172+
++line_count;
173+
a = line.substr(0, line.find(delimiter));
174+
narea = atoi(a.c_str());
175+
}
176+
n = line_count;
177+
myfile.close();
178+
}
179+
else {
180+
printf("Unable to open file %s", construction_dataset.c_str());
181+
exit(0);
182+
}
183+
184+
//determines the optimal bit_mapping and hash number
185+
int cells = (int)ceil((double)((double)-n*log(max_fpp)) / pow(log(2), 2));
186+
bit_mapping = (int)ceil(log2(cells));
187+
hn = (int)ceil((double)(cells / n)*log(2));
188+
189+
//constructs the filter and fills it with elements contained in the
190+
//input dataset
191+
try {
192+
//filter construction
193+
myFilter = new sbf::SBF(bit_mapping, hf, hn, narea, hash_salt);
194+
}
195+
catch (const std::invalid_argument& ia)
196+
{
197+
std::cerr << ia.what() << std::endl;
198+
}
199+
200+
myfile.open(construction_dataset.c_str());
201+
if (myfile.is_open()) {
202+
//elements insertion
203+
for (int i = 0; i < n; ++i)
204+
{
205+
//reads one line
206+
getline(myfile, line);
207+
a = line.substr(0, line.find(delimiter));
208+
area = atoi(a.c_str());
209+
member = line.substr(line.find(delimiter) + 1);
210+
len = member.length();
211+
element = new char[len];
212+
memcpy(element, member.c_str(), len);
213+
myFilter->Insert(element, len, area);
214+
}
215+
myfile.close();
216+
}
217+
else {
218+
printf("Unable to open file %s", construction_dataset.c_str());
219+
exit(0);
220+
}
221+
222+
//calculates filter's probabilistic properties
223+
myFilter->SetAreaFpp();
224+
225+
//prints filter to the standard output or saves it to disk
226+
if (print_mode == 1) myFilter->PrintFilter(0);
227+
if (print_mode == 2) myFilter->PrintFilter(1);
228+
if (print_mode == 3) {
229+
myFilter->SaveToDisk("filter" + buf + ".csv", 0);
230+
myFilter->SaveToDisk("stats" + buf + ".csv", 1);
231+
}
232+
233+
234+
//operates a self check upon the filter (i.e. runs the Check method for each
235+
//of the already mapped elements)
236+
well_recognised = 0, exchanged_elements = 0;
237+
myfile.open(construction_dataset.c_str());
238+
239+
if (myfile.is_open()) {
240+
printf("Self-check:\n");
241+
for (int i = 0; i < n; i++)
242+
{
243+
//reads one line
244+
getline(myfile, line);
245+
a = line.substr(0, line.find(delimiter));
246+
area = atoi(a.c_str());
247+
member = line.substr(line.find(delimiter) + 1);
248+
len = member.length();
249+
element = new char[len];
250+
memcpy(element, member.c_str(), len);
251+
area_check = myFilter->Check(element, len);
252+
253+
if (area == area_check) well_recognised++;
254+
else {
255+
exchanged_elements++;
256+
}
257+
258+
}
259+
printf("Well recognised: %d\n", well_recognised);
260+
printf("Elements assigned to a wrong set: %d\n", exchanged_elements);
261+
printf("Exchange rate: %f\n", (float)exchanged_elements / (float)n);
262+
myfile.close();
263+
}
264+
else {
265+
printf("Unable to open file %s", construction_dataset.c_str());
266+
exit(0);
267+
}
268+
269+
if (perform_verification) {
270+
271+
//determines the number of elements depending on the verification dataset
272+
myfile.open(verification_dataset.c_str());
273+
274+
if (myfile.is_open()) {
275+
line_count = 0;
276+
while (getline(myfile, line)) {
277+
++line_count;
278+
}
279+
nver = line_count;
280+
myfile.close();
281+
}
282+
else {
283+
printf("Unable to open file %s", verification_dataset.c_str());
284+
exit(0);
285+
}
286+
287+
//operates a verification using non members dataset
288+
well_recognised = 0, false_positives = 0;
289+
myfile.open(verification_dataset.c_str());
290+
291+
if (myfile.is_open()) {
292+
printf("\nVerification (non-elements):\n");
293+
for (int i = 0; i < nver; i++)
294+
{
295+
//reads one line
296+
getline(myfile, line);
297+
len = line.length();
298+
element = new char[len];
299+
memcpy(element, line.c_str(), len);
300+
area = myFilter->Check(element, len);
301+
302+
if (area == 0)well_recognised++;
303+
else false_positives++;
304+
}
305+
printf("Well recognised: %d\n", well_recognised);
306+
printf("False positives: %d\n", false_positives);
307+
printf("False positives rate: %f\n", (float)false_positives / (float)nver);
308+
myfile.close();
309+
}
310+
else {
311+
printf("Unable to open file %s", verification_dataset.c_str());
312+
exit(0);
313+
}
314+
}
315+
316+
printf("Press any key to continue\n");
317+
getline(std::cin, input);
318+
return 0;
319+
}

0 commit comments

Comments
 (0)