@@ -362,9 +362,7 @@ struct cache_ref_iterator {
362
362
struct ref_iterator base ;
363
363
364
364
/*
365
- * The number of levels currently on the stack. This is always
366
- * at least 1, because when it becomes zero the iteration is
367
- * ended and this struct is freed.
365
+ * The number of levels currently on the stack.
368
366
*/
369
367
size_t levels_nr ;
370
368
@@ -376,7 +374,7 @@ struct cache_ref_iterator {
376
374
* The prefix is matched textually, without regard for path
377
375
* component boundaries.
378
376
*/
379
- const char * prefix ;
377
+ char * prefix ;
380
378
381
379
/*
382
380
* A stack of levels. levels[0] is the uppermost level that is
@@ -389,13 +387,19 @@ struct cache_ref_iterator {
389
387
struct cache_ref_iterator_level * levels ;
390
388
391
389
struct repository * repo ;
390
+ struct ref_cache * cache ;
391
+
392
+ int prime_dir ;
392
393
};
393
394
394
395
static int cache_ref_iterator_advance (struct ref_iterator * ref_iterator )
395
396
{
396
397
struct cache_ref_iterator * iter =
397
398
(struct cache_ref_iterator * )ref_iterator ;
398
399
400
+ if (!iter -> levels_nr )
401
+ return ITER_DONE ;
402
+
399
403
while (1 ) {
400
404
struct cache_ref_iterator_level * level =
401
405
& iter -> levels [iter -> levels_nr - 1 ];
@@ -444,6 +448,41 @@ static int cache_ref_iterator_advance(struct ref_iterator *ref_iterator)
444
448
}
445
449
}
446
450
451
+ static int cache_ref_iterator_seek (struct ref_iterator * ref_iterator ,
452
+ const char * prefix )
453
+ {
454
+ struct cache_ref_iterator * iter =
455
+ (struct cache_ref_iterator * )ref_iterator ;
456
+ struct cache_ref_iterator_level * level ;
457
+ struct ref_dir * dir ;
458
+
459
+ dir = get_ref_dir (iter -> cache -> root );
460
+ if (prefix && * prefix )
461
+ dir = find_containing_dir (dir , prefix );
462
+ if (!dir ) {
463
+ iter -> levels_nr = 0 ;
464
+ return 0 ;
465
+ }
466
+
467
+ if (iter -> prime_dir )
468
+ prime_ref_dir (dir , prefix );
469
+ iter -> levels_nr = 1 ;
470
+ level = & iter -> levels [0 ];
471
+ level -> index = -1 ;
472
+ level -> dir = dir ;
473
+
474
+ if (prefix && * prefix ) {
475
+ free (iter -> prefix );
476
+ iter -> prefix = xstrdup (prefix );
477
+ level -> prefix_state = PREFIX_WITHIN_DIR ;
478
+ } else {
479
+ FREE_AND_NULL (iter -> prefix );
480
+ level -> prefix_state = PREFIX_CONTAINS_DIR ;
481
+ }
482
+
483
+ return 0 ;
484
+ }
485
+
447
486
static int cache_ref_iterator_peel (struct ref_iterator * ref_iterator ,
448
487
struct object_id * peeled )
449
488
{
@@ -456,12 +495,13 @@ static void cache_ref_iterator_release(struct ref_iterator *ref_iterator)
456
495
{
457
496
struct cache_ref_iterator * iter =
458
497
(struct cache_ref_iterator * )ref_iterator ;
459
- free (( char * ) iter -> prefix );
498
+ free (iter -> prefix );
460
499
free (iter -> levels );
461
500
}
462
501
463
502
static struct ref_iterator_vtable cache_ref_iterator_vtable = {
464
503
.advance = cache_ref_iterator_advance ,
504
+ .seek = cache_ref_iterator_seek ,
465
505
.peel = cache_ref_iterator_peel ,
466
506
.release = cache_ref_iterator_release ,
467
507
};
@@ -471,39 +511,22 @@ struct ref_iterator *cache_ref_iterator_begin(struct ref_cache *cache,
471
511
struct repository * repo ,
472
512
int prime_dir )
473
513
{
474
- struct ref_dir * dir ;
475
514
struct cache_ref_iterator * iter ;
476
515
struct ref_iterator * ref_iterator ;
477
- struct cache_ref_iterator_level * level ;
478
-
479
- dir = get_ref_dir (cache -> root );
480
- if (prefix && * prefix )
481
- dir = find_containing_dir (dir , prefix );
482
- if (!dir )
483
- /* There's nothing to iterate over. */
484
- return empty_ref_iterator_begin ();
485
-
486
- if (prime_dir )
487
- prime_ref_dir (dir , prefix );
488
516
489
517
CALLOC_ARRAY (iter , 1 );
490
518
ref_iterator = & iter -> base ;
491
519
base_ref_iterator_init (ref_iterator , & cache_ref_iterator_vtable );
492
520
ALLOC_GROW (iter -> levels , 10 , iter -> levels_alloc );
493
521
494
- iter -> levels_nr = 1 ;
495
- level = & iter -> levels [0 ];
496
- level -> index = -1 ;
497
- level -> dir = dir ;
522
+ iter -> repo = repo ;
523
+ iter -> cache = cache ;
524
+ iter -> prime_dir = prime_dir ;
498
525
499
- if (prefix && * prefix ) {
500
- iter -> prefix = xstrdup (prefix );
501
- level -> prefix_state = PREFIX_WITHIN_DIR ;
502
- } else {
503
- level -> prefix_state = PREFIX_CONTAINS_DIR ;
526
+ if (cache_ref_iterator_seek (& iter -> base , prefix ) < 0 ) {
527
+ ref_iterator_free (& iter -> base );
528
+ return NULL ;
504
529
}
505
530
506
- iter -> repo = repo ;
507
-
508
531
return ref_iterator ;
509
532
}
0 commit comments