-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathfastcci_build_db.cc
213 lines (174 loc) · 5.29 KB
/
fastcci_build_db.cc
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
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
#include "fastcci.h"
#include "errno.h"
int fd_cat, fd_tree;
int maxtree = 1024*128, maxcat = 1024*128;
tree_type *cat=NULL, *tree=NULL;
void growTree(int max=0) {
if (tree == NULL) {
if (ftruncate(fd_tree, maxtree * sizeof *tree))
printf("fruncate errno=%d fd=%d\n", errno, fd_tree);
tree = (tree_type*)mmap(NULL, maxtree * sizeof *tree, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_NORESERVE, fd_tree, 0);
} else {
int old_maxtree = maxtree;
maxtree *= 2;
if (maxtree<=max) maxtree = max+1;
if (ftruncate(fd_tree, maxtree * sizeof *tree))
printf("errno = %d\n", errno);
tree = (tree_type*)mremap(tree, old_maxtree * sizeof *tree, maxtree * sizeof *tree, MREMAP_MAYMOVE);
}
// check for allocation error
if (tree == MAP_FAILED) {
perror("growTree() MAP_FAILED");
exit(1);
}
if (tree == NULL) {
perror("growTree()");
exit(1);
}
// printf("grew tree to %d\n", maxtree);
}
void growCat(int max=0) {
int a = 0;
if (cat == NULL) {
if (ftruncate(fd_cat, maxcat * sizeof *cat))
printf("fruncate errno=%d fd=%d\n", errno, fd_cat);
cat = (tree_type*)mmap(NULL, maxcat * sizeof *cat, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_NORESERVE, fd_cat, 0);
} else {
a = maxcat;
maxcat *= 2;
if (maxcat<=max) maxcat = max+1;
ftruncate(fd_cat, maxcat * sizeof *cat);
cat = (tree_type*)mremap(cat, a * sizeof *cat, maxcat * sizeof *cat, MREMAP_MAYMOVE);
}
// check for allocation error
if (cat == MAP_FAILED) {
perror("growCat() MAP_FAILED");
exit(1);
}
if (cat == NULL) {
perror("growCat() NULL");
exit(1);
}
// initialize al cat entries to -1 (unused pageids are files)
for (int i=a; i<maxcat; ++i) cat[i] = -1;
// printf("grew cat to %d\n", maxcat);
}
int main(int argc, char *argv[]) {
int i, j;
// file descriptors for mmap
fd_cat = open("fastcci.cat", O_RDWR|O_CREAT, 0744);
if (fd_cat == -1) {
printf("Error opening cat file: %d\n", errno);
return 1;
}
fd_tree = open("fastcci.tree", O_RDWR|O_CREAT, 0744);
if (fd_tree == -1) {
printf("Error opening tree file: %d\n", errno);
return errno;
}
growCat();
growTree();
// insert empty dummy category at tree[0]
int cstart=2, cfile=2, csubcat=2;
tree[0] = 2;
tree[1] = 2;
// read data dump line by line
char buf[200], type[10];
int cl_from, cl_to, lcl_to=-1;
int expect; // 0:sf, 1:f
while (!feof(stdin)) {
if (fgets(buf, 200, stdin)) {
sscanf(buf,"%d %d %s", &cl_from, &cl_to, type);
// new category?
if (cl_to != lcl_to) {
if (lcl_to>0) {
// make sure we have enough memory for the index
if (lcl_to>=maxcat) growCat(lcl_to);
// write category index and category header
cat[lcl_to] = cstart;
tree[cstart] = csubcat;
tree[cstart+1] = cfile;
// pre-sort the file list
qsort(&(tree[csubcat]),cfile-csubcat,sizeof *tree,compare);
// expect a subcategory or a file
}
cstart = csubcat = cfile;
csubcat += 2;
cfile += 2;
}
if (cfile>=maxtree) growTree();
if (type[0]=='s') {
// is the cat index of this subcategory still -1, then set it to the empty dummy cat 0
if (cl_from>=maxcat) growCat(cl_from);
if (cat[cl_from]==-1) cat[cl_from]=0;
// no files in category yet?
if (csubcat==cfile) {
tree[csubcat++] = cl_from;
cfile++;
} else {
// we already have a file at tree[subcat], move it to the end of cfile
//fprintf(stderr,"out of order subcat!\n");
tree[cfile++] = tree[csubcat];
tree[csubcat++] = cl_from;
}
} else if (type[0]=='f') {
// just append at cfile
tree[cfile++] = cl_from;
}
lcl_to = cl_to;
}
}
// make sure we have enough memory for the index
if (lcl_to>=maxcat) growCat(lcl_to);
// close final category header
cat[lcl_to] = cstart;
tree[cstart] = csubcat;
tree[cstart+1] = cfile;
qsort(&(tree[csubcat]),cfile-csubcat,sizeof(int),compare);
// verify data
for (int i=0; i<=lcl_to; ++i) {
cstart = cat[i];
if (cstart<0) continue;
csubcat = tree[cstart];
cfile = tree[cstart+1];
cstart += 2;
if (csubcat<cstart) {
fprintf(stderr,"Negative subcat block length in cat %d\n", i);
exit(1);
}
if (cfile<csubcat) {
fprintf(stderr,"Negative file block length in cat %d\n", i);
exit(1);
}
// verify subcats
for (; cstart<csubcat; cstart++)
if (cat[tree[cstart]] < 0 ) {
fprintf(stderr,"File %d in subcat block of cat %d\n", tree[cstart], i);
exit(1);
}
// verify files
for (; cstart<cfile; cstart++)
if (cat[tree[cstart]] != -1 ) {
fprintf(stderr,"Category %d in file block of cat %d\n", tree[cstart], i);
exit(1);
}
}
// write out binary tree files
munmap(cat, maxcat * sizeof *cat);
munmap(tree, maxtree * sizeof *tree);
ftruncate(fd_tree, cfile * sizeof *tree);
ftruncate(fd_cat, (lcl_to+1) * sizeof *cat);
close(fd_tree);
close(fd_cat);
printf("db files written.\n");
// write success file
FILE *done = fopen("done", "w");
if (done)
{
fprintf(done, "OK\n");
fclose(done);
}
else
printf("Could not open file.\n");
return 0;
}