1 |
commit: 2fc9b2a308a7d72edede919956a0d290a72a7781 |
2 |
Author: Fabian Groffen <grobian <AT> gentoo <DOT> org> |
3 |
AuthorDate: Sun Apr 28 15:19:07 2019 +0000 |
4 |
Commit: Fabian Groffen <grobian <AT> gentoo <DOT> org> |
5 |
CommitDate: Sun Apr 28 15:19:07 2019 +0000 |
6 |
URL: https://gitweb.gentoo.org/proj/portage-utils.git/commit/?id=2fc9b2a3 |
7 |
|
8 |
libq/{vdb,cache}: unify sorted and unsorted traversal |
9 |
|
10 |
Get vdb to know some bits for cache, such that cache can be a more |
11 |
shallow wrapper around it. Use the same code to traverse in sorted mode |
12 |
by just keeping a temp list in the sorted case. |
13 |
|
14 |
Signed-off-by: Fabian Groffen <grobian <AT> gentoo.org> |
15 |
|
16 |
libq/cache.c | 137 ++++++++++++++++++------------------------------- |
17 |
libq/cache.h | 14 +---- |
18 |
libq/vdb.c | 164 ++++++++++++++++++++++++++++++++++------------------------- |
19 |
libq/vdb.h | 46 +++++++++++++---- |
20 |
qgrep.c | 4 +- |
21 |
5 files changed, 186 insertions(+), 179 deletions(-) |
22 |
|
23 |
diff --git a/libq/cache.c b/libq/cache.c |
24 |
index 7724287..a00dd6b 100644 |
25 |
--- a/libq/cache.c |
26 |
+++ b/libq/cache.c |
27 |
@@ -53,46 +53,43 @@ static const char portrepo_name[] = "profiles/repo_name"; |
28 |
cache_ctx * |
29 |
cache_open(const char *sroot, const char *portdir) |
30 |
{ |
31 |
- q_vdb_ctx *dir; |
32 |
cache_ctx *ret; |
33 |
char buf[_Q_PATH_MAX]; |
34 |
+ char *repo = NULL; |
35 |
size_t repolen = 0; |
36 |
|
37 |
- ret = xzalloc(sizeof(cache_ctx)); |
38 |
- |
39 |
snprintf(buf, sizeof(buf), "%s%s/%s", sroot, portdir, portrepo_name); |
40 |
- if (eat_file(buf, &ret->repo, &repolen)) { |
41 |
- (void)rmspace(ret->repo); |
42 |
+ if (eat_file(buf, &repo, &repolen)) { |
43 |
+ (void)rmspace(repo); |
44 |
} else { |
45 |
- ret->repo = NULL; /* ignore missing repo file */ |
46 |
+ repo = NULL; /* ignore missing repo file */ |
47 |
} |
48 |
|
49 |
snprintf(buf, sizeof(buf), "%s/%s", portdir, portcachedir_md5); |
50 |
- dir = q_vdb_open2(sroot, buf, true); |
51 |
- if (dir != NULL) { |
52 |
- ret->dir_ctx = dir; |
53 |
+ ret = q_vdb_open2(sroot, buf, true); |
54 |
+ if (ret != NULL) { |
55 |
ret->cachetype = CACHE_METADATA_MD5; |
56 |
+ ret->repo = repo; |
57 |
return ret; |
58 |
} |
59 |
|
60 |
snprintf(buf, sizeof(buf), "%s/%s", portdir, portcachedir_pms); |
61 |
- dir = q_vdb_open2(sroot, buf, true); |
62 |
- if (dir != NULL) { |
63 |
- ret->dir_ctx = dir; |
64 |
+ ret = q_vdb_open2(sroot, buf, true); |
65 |
+ if (ret != NULL) { |
66 |
ret->cachetype = CACHE_METADATA_PMS; |
67 |
+ ret->repo = repo; |
68 |
return ret; |
69 |
} |
70 |
|
71 |
- dir = q_vdb_open2(sroot, portdir, true); |
72 |
- if (dir != NULL) { |
73 |
- ret->dir_ctx = dir; |
74 |
+ ret = q_vdb_open2(sroot, portdir, true); |
75 |
+ if (ret != NULL) { |
76 |
ret->cachetype = CACHE_EBUILD; |
77 |
+ ret->repo = repo; |
78 |
return ret; |
79 |
} |
80 |
|
81 |
cache_close(ret); |
82 |
- warnf("could not open repository at %s (under root %s)", |
83 |
- portdir, sroot); |
84 |
+ warnf("could not open repository at %s (under root %s)", portdir, sroot); |
85 |
|
86 |
return NULL; |
87 |
} |
88 |
@@ -100,49 +97,41 @@ cache_open(const char *sroot, const char *portdir) |
89 |
void |
90 |
cache_close(cache_ctx *ctx) |
91 |
{ |
92 |
- if (ctx->dir_ctx != NULL) |
93 |
- q_vdb_close(ctx->dir_ctx); |
94 |
if (ctx->repo != NULL) |
95 |
free(ctx->repo); |
96 |
- free(ctx); |
97 |
+ if (ctx->ebuilddir_ctx != NULL) |
98 |
+ free(ctx->ebuilddir_ctx); |
99 |
+ q_vdb_close(ctx); |
100 |
} |
101 |
|
102 |
cache_cat_ctx * |
103 |
cache_open_cat(cache_ctx *ctx, const char *name) |
104 |
{ |
105 |
- cache_cat_ctx *ret = q_vdb_open_cat(ctx->dir_ctx, name); |
106 |
- if (ret != NULL) |
107 |
- ret->ctx = (q_vdb_ctx *)ctx; |
108 |
- return ret; |
109 |
+ return q_vdb_open_cat(ctx, name); |
110 |
} |
111 |
|
112 |
cache_cat_ctx * |
113 |
cache_next_cat(cache_ctx *ctx) |
114 |
{ |
115 |
- cache_cat_ctx *ret = q_vdb_next_cat(ctx->dir_ctx); |
116 |
- if (ret != NULL) |
117 |
- ret->ctx = (q_vdb_ctx *)ctx; |
118 |
- return ret; |
119 |
+ return q_vdb_next_cat(ctx); |
120 |
} |
121 |
|
122 |
void |
123 |
cache_close_cat(cache_cat_ctx *cat_ctx) |
124 |
{ |
125 |
- q_vdb_close_cat(cat_ctx); |
126 |
+ return q_vdb_close_cat(cat_ctx); |
127 |
} |
128 |
|
129 |
cache_pkg_ctx * |
130 |
cache_open_pkg(cache_cat_ctx *cat_ctx, const char *name) |
131 |
{ |
132 |
- cache_pkg_ctx *ret = q_vdb_open_pkg(cat_ctx, name); |
133 |
- ret->repo = ((cache_ctx *)cat_ctx->ctx)->repo; |
134 |
- return ret; |
135 |
+ return q_vdb_open_pkg(cat_ctx, name); |
136 |
} |
137 |
|
138 |
cache_pkg_ctx * |
139 |
cache_next_pkg(cache_cat_ctx *cat_ctx) |
140 |
{ |
141 |
- cache_ctx *ctx = (cache_ctx *)(cat_ctx->ctx); |
142 |
+ cache_ctx *ctx = (cache_ctx *)cat_ctx->ctx; |
143 |
cache_pkg_ctx *ret = NULL; |
144 |
|
145 |
if (ctx->cachetype == CACHE_EBUILD) { |
146 |
@@ -152,7 +141,10 @@ cache_next_pkg(cache_cat_ctx *cat_ctx) |
147 |
* to CAT/P like in VDB and metadata */ |
148 |
do { |
149 |
if (ctx->ebuilddir_pkg_ctx == NULL) { |
150 |
- q_vdb_ctx *pkgdir = &ctx->ebuilddir_ctx; |
151 |
+ q_vdb_ctx *pkgdir = ctx->ebuilddir_ctx; |
152 |
+ |
153 |
+ if (pkgdir == NULL) |
154 |
+ pkgdir = ctx->ebuilddir_ctx = xzalloc(sizeof(q_vdb_ctx)); |
155 |
|
156 |
if ((ctx->ebuilddir_pkg_ctx = q_vdb_next_pkg(cat_ctx)) == NULL) |
157 |
return NULL; |
158 |
@@ -492,14 +484,16 @@ void |
159 |
cache_close_pkg(cache_pkg_ctx *pkg_ctx) |
160 |
{ |
161 |
/* avoid free of cache_ctx' repo by q_vdb_close_pkg */ |
162 |
- if (((cache_ctx *)pkg_ctx->cat_ctx->ctx)->repo == pkg_ctx->repo) |
163 |
+ if (pkg_ctx->cat_ctx->ctx->repo == pkg_ctx->repo) |
164 |
pkg_ctx->repo = NULL; |
165 |
+ |
166 |
q_vdb_close_pkg(pkg_ctx); |
167 |
} |
168 |
|
169 |
-int |
170 |
-cache_foreach_pkg(const char *sroot, const char *portdir, |
171 |
- q_vdb_pkg_cb callback, void *priv, q_vdb_cat_filter filter) |
172 |
+static int |
173 |
+cache_foreach_pkg_int(const char *sroot, const char *portdir, |
174 |
+ q_vdb_pkg_cb callback, void *priv, q_vdb_cat_filter filter, |
175 |
+ bool sort, void *catsortfunc, void *pkgsortfunc) |
176 |
{ |
177 |
cache_ctx *ctx; |
178 |
cache_cat_ctx *cat_ctx; |
179 |
@@ -510,6 +504,12 @@ cache_foreach_pkg(const char *sroot, const char *portdir, |
180 |
if (!ctx) |
181 |
return EXIT_FAILURE; |
182 |
|
183 |
+ ctx->do_sort = sort; |
184 |
+ if (catsortfunc != NULL) |
185 |
+ ctx->catsortfunc = catsortfunc; |
186 |
+ if (pkgsortfunc != NULL) |
187 |
+ ctx->pkgsortfunc = pkgsortfunc; |
188 |
+ |
189 |
ret = 0; |
190 |
while ((cat_ctx = cache_next_cat(ctx))) { |
191 |
if (filter && !filter(cat_ctx, priv)) |
192 |
@@ -518,63 +518,26 @@ cache_foreach_pkg(const char *sroot, const char *portdir, |
193 |
ret |= callback(pkg_ctx, priv); |
194 |
cache_close_pkg(pkg_ctx); |
195 |
} |
196 |
+ cache_close_cat(cat_ctx); |
197 |
} |
198 |
+ cache_close(ctx); |
199 |
|
200 |
return ret; |
201 |
} |
202 |
|
203 |
+int |
204 |
+cache_foreach_pkg(const char *sroot, const char *portdir, |
205 |
+ q_vdb_pkg_cb callback, void *priv, q_vdb_cat_filter filter) |
206 |
+{ |
207 |
+ return cache_foreach_pkg_int(sroot, portdir, callback, priv, |
208 |
+ filter, false, NULL, NULL); |
209 |
+} |
210 |
+ |
211 |
int |
212 |
cache_foreach_pkg_sorted(const char *sroot, const char *portdir, |
213 |
q_vdb_pkg_cb callback, void *priv, |
214 |
void *catsortfunc, void *pkgsortfunc) |
215 |
{ |
216 |
- cache_ctx *ctx; |
217 |
- cache_cat_ctx *cat_ctx; |
218 |
- cache_pkg_ctx *pkg_ctx; |
219 |
- int ret = 0; |
220 |
- int c; |
221 |
- int p; |
222 |
- int cat_cnt; |
223 |
- int pkg_cnt; |
224 |
- struct dirent **cat_de; |
225 |
- struct dirent **pkg_de; |
226 |
- |
227 |
- ctx = cache_open(sroot, portdir); |
228 |
- if (!ctx) |
229 |
- return EXIT_FAILURE; |
230 |
- |
231 |
- if (catsortfunc == NULL) |
232 |
- catsortfunc = alphasort; |
233 |
- if (pkgsortfunc == NULL) |
234 |
- pkgsortfunc = alphasort; |
235 |
- |
236 |
- cat_cnt = scandirat(ctx->dir_ctx->vdb_fd, |
237 |
- ".", &cat_de, q_vdb_filter_cat, catsortfunc); |
238 |
- for (c = 0; c < cat_cnt; c++) { |
239 |
- cat_ctx = cache_open_cat(ctx, cat_de[c]->d_name); |
240 |
- if (!cat_ctx) |
241 |
- continue; |
242 |
- |
243 |
- pkg_cnt = scandirat(ctx->dir_ctx->vdb_fd, |
244 |
- cat_de[c]->d_name, &pkg_de, q_vdb_filter_pkg, pkgsortfunc); |
245 |
- for (p = 0; p < pkg_cnt; p++) { |
246 |
- if (pkg_de[p]->d_name[0] == '-') |
247 |
- continue; |
248 |
- |
249 |
- pkg_ctx = cache_open_pkg(cat_ctx, pkg_de[p]->d_name); |
250 |
- if (!pkg_ctx) |
251 |
- continue; |
252 |
- |
253 |
- ret |= callback(pkg_ctx, priv); |
254 |
- |
255 |
- cache_close_pkg(pkg_ctx); |
256 |
- } |
257 |
- scandir_free(pkg_de, pkg_cnt); |
258 |
- |
259 |
- cache_close_cat(cat_ctx); |
260 |
- } |
261 |
- scandir_free(cat_de, cat_cnt); |
262 |
- |
263 |
- cache_close(ctx); |
264 |
- return ret; |
265 |
+ return cache_foreach_pkg_int(sroot, portdir, callback, priv, |
266 |
+ NULL, true, catsortfunc, pkgsortfunc); |
267 |
} |
268 |
|
269 |
diff --git a/libq/cache.h b/libq/cache.h |
270 |
index 0157824..f9b1d43 100644 |
271 |
--- a/libq/cache.h |
272 |
+++ b/libq/cache.h |
273 |
@@ -13,19 +13,7 @@ |
274 |
#include "atom.h" |
275 |
#include "vdb.h" |
276 |
|
277 |
-typedef struct cache_ctx { |
278 |
- q_vdb_ctx *dir_ctx; |
279 |
- enum { |
280 |
- CACHE_UNSET = 0, |
281 |
- CACHE_METADATA_MD5, |
282 |
- CACHE_METADATA_PMS, |
283 |
- CACHE_EBUILD, |
284 |
- } cachetype; |
285 |
- q_vdb_pkg_ctx *ebuilddir_pkg_ctx; |
286 |
- q_vdb_cat_ctx *ebuilddir_cat_ctx; |
287 |
- q_vdb_ctx ebuilddir_ctx; |
288 |
- char *repo; |
289 |
-} cache_ctx; |
290 |
+#define cache_ctx q_vdb_ctx |
291 |
#define cache_cat_ctx q_vdb_cat_ctx |
292 |
#define cache_pkg_ctx q_vdb_pkg_ctx |
293 |
|
294 |
|
295 |
diff --git a/libq/vdb.c b/libq/vdb.c |
296 |
index a32ba53..9c53b5b 100644 |
297 |
--- a/libq/vdb.c |
298 |
+++ b/libq/vdb.c |
299 |
@@ -45,6 +45,13 @@ q_vdb_open2(const char *sroot, const char *svdb, bool quiet) |
300 |
if (ctx->dir == NULL) |
301 |
goto cv_error; |
302 |
|
303 |
+ ctx->do_sort = false; |
304 |
+ ctx->cat_de = NULL; |
305 |
+ ctx->catsortfunc = alphasort; |
306 |
+ ctx->pkgsortfunc = alphasort; |
307 |
+ ctx->repo = NULL; |
308 |
+ ctx->ebuilddir_ctx = NULL; |
309 |
+ ctx->ebuilddir_pkg_ctx = NULL; |
310 |
return ctx; |
311 |
|
312 |
cv_error: |
313 |
@@ -69,6 +76,8 @@ q_vdb_close(q_vdb_ctx *ctx) |
314 |
/* closedir() above does this for us: */ |
315 |
/* close(ctx->vdb_fd); */ |
316 |
close(ctx->portroot_fd); |
317 |
+ if (ctx->do_sort) |
318 |
+ scandir_free(ctx->cat_de, ctx->cat_cnt); |
319 |
free(ctx); |
320 |
} |
321 |
|
322 |
@@ -136,6 +145,7 @@ q_vdb_open_cat(q_vdb_ctx *ctx, const char *name) |
323 |
cat_ctx->fd = fd; |
324 |
cat_ctx->dir = dir; |
325 |
cat_ctx->ctx = ctx; |
326 |
+ cat_ctx->pkg_de = NULL; |
327 |
return cat_ctx; |
328 |
} |
329 |
|
330 |
@@ -143,22 +153,39 @@ q_vdb_cat_ctx * |
331 |
q_vdb_next_cat(q_vdb_ctx *ctx) |
332 |
{ |
333 |
/* search for a category directory */ |
334 |
- q_vdb_cat_ctx *cat_ctx; |
335 |
- const struct dirent *de; |
336 |
+ q_vdb_cat_ctx *cat_ctx = NULL; |
337 |
|
338 |
- next_cat: |
339 |
- de = readdir(ctx->dir); |
340 |
- if (!de) { |
341 |
- q_vdb_close(ctx); |
342 |
- return NULL; |
343 |
- } |
344 |
+ if (ctx->do_sort) { |
345 |
+ if (ctx->cat_de == NULL) { |
346 |
+ ctx->cat_cnt = scandirat(ctx->vdb_fd, |
347 |
+ ".", &ctx->cat_de, q_vdb_filter_cat, ctx->catsortfunc); |
348 |
+ ctx->cat_cur = 0; |
349 |
+ } |
350 |
+ |
351 |
+ while (ctx->cat_cur < ctx->cat_cnt) { |
352 |
+ cat_ctx = q_vdb_open_cat(ctx, ctx->cat_de[ctx->cat_cur++]->d_name); |
353 |
+ if (!cat_ctx) |
354 |
+ continue; |
355 |
+ break; |
356 |
+ } |
357 |
+ } else { |
358 |
+ /* cheaper "streaming" variant */ |
359 |
+ const struct dirent *de; |
360 |
+ do { |
361 |
+ de = readdir(ctx->dir); |
362 |
+ if (!de) |
363 |
+ break; |
364 |
|
365 |
- if (q_vdb_filter_cat(de) == 0) |
366 |
- goto next_cat; |
367 |
+ if (q_vdb_filter_cat(de) == 0) |
368 |
+ continue; |
369 |
+ |
370 |
+ cat_ctx = q_vdb_open_cat(ctx, de->d_name); |
371 |
+ if (!cat_ctx) |
372 |
+ continue; |
373 |
|
374 |
- cat_ctx = q_vdb_open_cat(ctx, de->d_name); |
375 |
- if (!cat_ctx) |
376 |
- goto next_cat; |
377 |
+ break; |
378 |
+ } while (1); |
379 |
+ } |
380 |
|
381 |
return cat_ctx; |
382 |
} |
383 |
@@ -169,6 +196,8 @@ q_vdb_close_cat(q_vdb_cat_ctx *cat_ctx) |
384 |
closedir(cat_ctx->dir); |
385 |
/* closedir() above does this for us: */ |
386 |
/* close(ctx->fd); */ |
387 |
+ if (cat_ctx->ctx->do_sort) |
388 |
+ scandir_free(cat_ctx->pkg_de, cat_ctx->pkg_cnt); |
389 |
free(cat_ctx); |
390 |
} |
391 |
|
392 |
@@ -194,7 +223,7 @@ q_vdb_open_pkg(q_vdb_cat_ctx *cat_ctx, const char *name) |
393 |
q_vdb_pkg_ctx *pkg_ctx = xmalloc(sizeof(*pkg_ctx)); |
394 |
pkg_ctx->name = name; |
395 |
pkg_ctx->slot = NULL; |
396 |
- pkg_ctx->repo = NULL; |
397 |
+ pkg_ctx->repo = cat_ctx->ctx->repo; |
398 |
pkg_ctx->fd = -1; |
399 |
pkg_ctx->cat_ctx = cat_ctx; |
400 |
return pkg_ctx; |
401 |
@@ -203,22 +232,40 @@ q_vdb_open_pkg(q_vdb_cat_ctx *cat_ctx, const char *name) |
402 |
q_vdb_pkg_ctx * |
403 |
q_vdb_next_pkg(q_vdb_cat_ctx *cat_ctx) |
404 |
{ |
405 |
- q_vdb_pkg_ctx *pkg_ctx; |
406 |
- const struct dirent *de; |
407 |
+ q_vdb_pkg_ctx *pkg_ctx = NULL; |
408 |
|
409 |
- next_pkg: |
410 |
- de = readdir(cat_ctx->dir); |
411 |
- if (!de) { |
412 |
- q_vdb_close_cat(cat_ctx); |
413 |
- return NULL; |
414 |
- } |
415 |
+ if (cat_ctx->ctx->do_sort) { |
416 |
+ if (cat_ctx->pkg_de == NULL) { |
417 |
+ cat_ctx->pkg_cnt = scandirat(cat_ctx->fd, ".", &cat_ctx->pkg_de, |
418 |
+ q_vdb_filter_pkg, cat_ctx->ctx->pkgsortfunc); |
419 |
+ cat_ctx->pkg_cur = 0; |
420 |
+ } |
421 |
+ |
422 |
+ while (cat_ctx->pkg_cur < cat_ctx->pkg_cnt) { |
423 |
+ pkg_ctx = |
424 |
+ q_vdb_open_pkg(cat_ctx, |
425 |
+ cat_ctx->pkg_de[cat_ctx->pkg_cur++]->d_name); |
426 |
+ if (!pkg_ctx) |
427 |
+ continue; |
428 |
+ break; |
429 |
+ } |
430 |
+ } else { |
431 |
+ const struct dirent *de; |
432 |
+ do { |
433 |
+ de = readdir(cat_ctx->dir); |
434 |
+ if (!de) |
435 |
+ break; |
436 |
+ |
437 |
+ if (q_vdb_filter_pkg(de) == 0) |
438 |
+ continue; |
439 |
|
440 |
- if (q_vdb_filter_pkg(de) == 0) |
441 |
- goto next_pkg; |
442 |
+ pkg_ctx = q_vdb_open_pkg(cat_ctx, de->d_name); |
443 |
+ if (!pkg_ctx) |
444 |
+ continue; |
445 |
|
446 |
- pkg_ctx = q_vdb_open_pkg(cat_ctx, de->d_name); |
447 |
- if (!pkg_ctx) |
448 |
- goto next_pkg; |
449 |
+ break; |
450 |
+ } while (1); |
451 |
+ } |
452 |
|
453 |
return pkg_ctx; |
454 |
} |
455 |
@@ -275,9 +322,10 @@ q_vdb_close_pkg(q_vdb_pkg_ctx *pkg_ctx) |
456 |
free(pkg_ctx); |
457 |
} |
458 |
|
459 |
-int |
460 |
-q_vdb_foreach_pkg(const char *sroot, const char *svdb, |
461 |
- q_vdb_pkg_cb callback, void *priv, q_vdb_cat_filter filter) |
462 |
+static int |
463 |
+q_vdb_foreach_pkg_int(const char *sroot, const char *svdb, |
464 |
+ q_vdb_pkg_cb callback, void *priv, q_vdb_cat_filter filter, |
465 |
+ bool sort, void *catsortfunc, void *pkgsortfunc) |
466 |
{ |
467 |
q_vdb_ctx *ctx; |
468 |
q_vdb_cat_ctx *cat_ctx; |
469 |
@@ -288,6 +336,12 @@ q_vdb_foreach_pkg(const char *sroot, const char *svdb, |
470 |
if (!ctx) |
471 |
return EXIT_FAILURE; |
472 |
|
473 |
+ ctx->do_sort = sort; |
474 |
+ if (catsortfunc != NULL) |
475 |
+ ctx->catsortfunc = catsortfunc; |
476 |
+ if (pkgsortfunc != NULL) |
477 |
+ ctx->pkgsortfunc = pkgsortfunc; |
478 |
+ |
479 |
ret = 0; |
480 |
while ((cat_ctx = q_vdb_next_cat(ctx))) { |
481 |
if (filter && !filter(cat_ctx, priv)) |
482 |
@@ -296,53 +350,27 @@ q_vdb_foreach_pkg(const char *sroot, const char *svdb, |
483 |
ret |= callback(pkg_ctx, priv); |
484 |
q_vdb_close_pkg(pkg_ctx); |
485 |
} |
486 |
+ q_vdb_close_cat(cat_ctx); |
487 |
} |
488 |
+ q_vdb_close(ctx); |
489 |
|
490 |
return ret; |
491 |
} |
492 |
|
493 |
+int |
494 |
+q_vdb_foreach_pkg(const char *sroot, const char *svdb, |
495 |
+ q_vdb_pkg_cb callback, void *priv, q_vdb_cat_filter filter) |
496 |
+{ |
497 |
+ return q_vdb_foreach_pkg_int(sroot, svdb, callback, priv, |
498 |
+ filter, false, NULL, NULL); |
499 |
+} |
500 |
+ |
501 |
int |
502 |
q_vdb_foreach_pkg_sorted(const char *sroot, const char *svdb, |
503 |
q_vdb_pkg_cb callback, void *priv) |
504 |
{ |
505 |
- q_vdb_ctx *ctx; |
506 |
- q_vdb_cat_ctx *cat_ctx; |
507 |
- q_vdb_pkg_ctx *pkg_ctx; |
508 |
- int ret = 0; |
509 |
- int c, p, cat_cnt, pkg_cnt; |
510 |
- struct dirent **cat_de, **pkg_de; |
511 |
- |
512 |
- ctx = q_vdb_open(sroot, svdb); |
513 |
- if (!ctx) |
514 |
- return EXIT_FAILURE; |
515 |
- |
516 |
- cat_cnt = scandirat(ctx->vdb_fd, ".", &cat_de, q_vdb_filter_cat, alphasort); |
517 |
- for (c = 0; c < cat_cnt; ++c) { |
518 |
- cat_ctx = q_vdb_open_cat(ctx, cat_de[c]->d_name); |
519 |
- if (!cat_ctx) |
520 |
- continue; |
521 |
- |
522 |
- pkg_cnt = scandirat(ctx->vdb_fd, cat_de[c]->d_name, &pkg_de, q_vdb_filter_pkg, alphasort); |
523 |
- for (p = 0; p < pkg_cnt; ++p) { |
524 |
- if (pkg_de[p]->d_name[0] == '-') |
525 |
- continue; |
526 |
- |
527 |
- pkg_ctx = q_vdb_open_pkg(cat_ctx, pkg_de[p]->d_name); |
528 |
- if (!pkg_ctx) |
529 |
- continue; |
530 |
- |
531 |
- ret |= callback(pkg_ctx, priv); |
532 |
- |
533 |
- q_vdb_close_pkg(pkg_ctx); |
534 |
- } |
535 |
- scandir_free(pkg_de, pkg_cnt); |
536 |
- |
537 |
- q_vdb_close_cat(cat_ctx); |
538 |
- } |
539 |
- scandir_free(cat_de, cat_cnt); |
540 |
- |
541 |
- q_vdb_close(ctx); |
542 |
- return ret; |
543 |
+ return q_vdb_foreach_pkg_int(sroot, svdb, callback, priv, |
544 |
+ NULL, true, NULL, NULL); |
545 |
} |
546 |
|
547 |
struct dirent * |
548 |
|
549 |
diff --git a/libq/vdb.h b/libq/vdb.h |
550 |
index 102f5a9..ee2ee69 100644 |
551 |
--- a/libq/vdb.h |
552 |
+++ b/libq/vdb.h |
553 |
@@ -7,31 +7,59 @@ |
554 |
#define _VDB_H 1 |
555 |
|
556 |
#include <dirent.h> |
557 |
+#include <stdbool.h> |
558 |
|
559 |
#include "set.h" |
560 |
|
561 |
+typedef struct q_vdb_ctx q_vdb_ctx; |
562 |
+typedef struct q_vdb_cat_ctx q_vdb_cat_ctx; |
563 |
+typedef struct q_vdb_pkg_ctx q_vdb_pkg_ctx; |
564 |
+ |
565 |
/* VDB context */ |
566 |
-typedef struct { |
567 |
- int portroot_fd, vdb_fd; |
568 |
+struct q_vdb_ctx { |
569 |
+ int portroot_fd; |
570 |
+ int vdb_fd; |
571 |
DIR *dir; |
572 |
-} q_vdb_ctx; |
573 |
+ struct dirent **cat_de; |
574 |
+ size_t cat_cnt; |
575 |
+ size_t cat_cur; |
576 |
+ void *catsortfunc; |
577 |
+ void *pkgsortfunc; |
578 |
+ bool do_sort:1; |
579 |
+ enum { |
580 |
+ CACHE_UNSET = 0, |
581 |
+ CACHE_METADATA_MD5, |
582 |
+ CACHE_METADATA_PMS, |
583 |
+ CACHE_EBUILD, |
584 |
+ CACHE_VDB, |
585 |
+ } cachetype:3; |
586 |
+ q_vdb_pkg_ctx *ebuilddir_pkg_ctx; |
587 |
+ q_vdb_cat_ctx *ebuilddir_cat_ctx; |
588 |
+ q_vdb_ctx *ebuilddir_ctx; |
589 |
+ char *repo; |
590 |
+}; |
591 |
|
592 |
/* Category context */ |
593 |
-typedef struct { |
594 |
+struct q_vdb_cat_ctx { |
595 |
const char *name; |
596 |
int fd; |
597 |
DIR *dir; |
598 |
const q_vdb_ctx *ctx; |
599 |
-} q_vdb_cat_ctx; |
600 |
+ struct dirent **pkg_de; |
601 |
+ size_t pkg_cnt; |
602 |
+ size_t pkg_cur; |
603 |
+}; |
604 |
|
605 |
/* Package context */ |
606 |
-typedef struct { |
607 |
+struct q_vdb_pkg_ctx { |
608 |
const char *name; |
609 |
- char *slot, *repo; |
610 |
- size_t slot_len, repo_len; |
611 |
+ char *slot; |
612 |
+ char *repo; |
613 |
+ size_t slot_len; |
614 |
+ size_t repo_len; |
615 |
int fd; |
616 |
q_vdb_cat_ctx *cat_ctx; |
617 |
-} q_vdb_pkg_ctx; |
618 |
+}; |
619 |
|
620 |
/* Global helpers */ |
621 |
typedef int (q_vdb_pkg_cb)(q_vdb_pkg_ctx *, void *priv); |
622 |
|
623 |
diff --git a/qgrep.c b/qgrep.c |
624 |
index 9d78c18..6cb5697 100644 |
625 |
--- a/qgrep.c |
626 |
+++ b/qgrep.c |
627 |
@@ -413,9 +413,9 @@ qgrep_cache_cb(cache_pkg_ctx *pkg_ctx, void *priv) |
628 |
/* need to construct path in portdir to ebuild, pass it to grep */ |
629 |
cctx = (cache_ctx *)(pkg_ctx->cat_ctx->ctx); |
630 |
if (cctx->cachetype == CACHE_EBUILD) { |
631 |
- pfd = cctx->dir_ctx->vdb_fd; |
632 |
+ pfd = cctx->vdb_fd; |
633 |
} else { |
634 |
- pfd = openat(cctx->dir_ctx->vdb_fd, "../..", O_RDONLY|O_CLOEXEC); |
635 |
+ pfd = openat(cctx->vdb_fd, "../..", O_RDONLY|O_CLOEXEC); |
636 |
} |
637 |
|
638 |
/* cat/pkg/pkg-ver.ebuild */ |