@@ -162,58 +162,6 @@ static int parse_footer(struct reftable_reader *r, uint8_t *footer,
162
162
return err ;
163
163
}
164
164
165
- int init_reader (struct reftable_reader * r , struct reftable_block_source * source ,
166
- const char * name )
167
- {
168
- struct reftable_block footer = { NULL };
169
- struct reftable_block header = { NULL };
170
- int err = 0 ;
171
- uint64_t file_size = block_source_size (source );
172
-
173
- /* Need +1 to read type of first block. */
174
- uint32_t read_size = header_size (2 ) + 1 ; /* read v2 because it's larger. */
175
- memset (r , 0 , sizeof (struct reftable_reader ));
176
-
177
- if (read_size > file_size ) {
178
- err = REFTABLE_FORMAT_ERROR ;
179
- goto done ;
180
- }
181
-
182
- err = block_source_read_block (source , & header , 0 , read_size );
183
- if (err != read_size ) {
184
- err = REFTABLE_IO_ERROR ;
185
- goto done ;
186
- }
187
-
188
- if (memcmp (header .data , "REFT" , 4 )) {
189
- err = REFTABLE_FORMAT_ERROR ;
190
- goto done ;
191
- }
192
- r -> version = header .data [4 ];
193
- if (r -> version != 1 && r -> version != 2 ) {
194
- err = REFTABLE_FORMAT_ERROR ;
195
- goto done ;
196
- }
197
-
198
- r -> size = file_size - footer_size (r -> version );
199
- r -> source = * source ;
200
- r -> name = xstrdup (name );
201
- r -> hash_id = 0 ;
202
-
203
- err = block_source_read_block (source , & footer , r -> size ,
204
- footer_size (r -> version ));
205
- if (err != footer_size (r -> version )) {
206
- err = REFTABLE_IO_ERROR ;
207
- goto done ;
208
- }
209
-
210
- err = parse_footer (r , footer .data , header .data );
211
- done :
212
- reftable_block_done (& footer );
213
- reftable_block_done (& header );
214
- return err ;
215
- }
216
-
217
165
struct table_iter {
218
166
struct reftable_reader * r ;
219
167
uint8_t typ ;
@@ -227,6 +175,7 @@ static int table_iter_init(struct table_iter *ti, struct reftable_reader *r)
227
175
{
228
176
struct block_iter bi = BLOCK_ITER_INIT ;
229
177
memset (ti , 0 , sizeof (* ti ));
178
+ reftable_reader_incref (r );
230
179
ti -> r = r ;
231
180
ti -> bi = bi ;
232
181
return 0 ;
@@ -314,6 +263,7 @@ static void table_iter_close(struct table_iter *ti)
314
263
{
315
264
table_iter_block_done (ti );
316
265
block_iter_close (& ti -> bi );
266
+ reftable_reader_decref (ti -> r );
317
267
}
318
268
319
269
static int table_iter_next_block (struct table_iter * ti )
@@ -631,31 +581,90 @@ void reftable_reader_init_log_iterator(struct reftable_reader *r,
631
581
reader_init_iter (r , it , BLOCK_TYPE_LOG );
632
582
}
633
583
634
- void reader_close (struct reftable_reader * r )
584
+ int reftable_reader_new (struct reftable_reader * * out ,
585
+ struct reftable_block_source * source , char const * name )
635
586
{
636
- block_source_close (& r -> source );
637
- FREE_AND_NULL (r -> name );
638
- }
587
+ struct reftable_block footer = { 0 };
588
+ struct reftable_block header = { 0 };
589
+ struct reftable_reader * r ;
590
+ uint64_t file_size = block_source_size (source );
591
+ uint32_t read_size ;
592
+ int err ;
639
593
640
- int reftable_new_reader (struct reftable_reader * * p ,
641
- struct reftable_block_source * src , char const * name )
642
- {
643
- struct reftable_reader * rd = reftable_calloc (1 , sizeof (* rd ));
644
- int err = init_reader (rd , src , name );
645
- if (err == 0 ) {
646
- * p = rd ;
647
- } else {
648
- block_source_close (src );
649
- reftable_free (rd );
594
+ REFTABLE_CALLOC_ARRAY (r , 1 );
595
+
596
+ /*
597
+ * We need one extra byte to read the type of first block. We also
598
+ * pretend to always be reading v2 of the format because it is larger.
599
+ */
600
+ read_size = header_size (2 ) + 1 ;
601
+ if (read_size > file_size ) {
602
+ err = REFTABLE_FORMAT_ERROR ;
603
+ goto done ;
604
+ }
605
+
606
+ err = block_source_read_block (source , & header , 0 , read_size );
607
+ if (err != read_size ) {
608
+ err = REFTABLE_IO_ERROR ;
609
+ goto done ;
610
+ }
611
+
612
+ if (memcmp (header .data , "REFT" , 4 )) {
613
+ err = REFTABLE_FORMAT_ERROR ;
614
+ goto done ;
615
+ }
616
+ r -> version = header .data [4 ];
617
+ if (r -> version != 1 && r -> version != 2 ) {
618
+ err = REFTABLE_FORMAT_ERROR ;
619
+ goto done ;
620
+ }
621
+
622
+ r -> size = file_size - footer_size (r -> version );
623
+ r -> source = * source ;
624
+ r -> name = xstrdup (name );
625
+ r -> hash_id = 0 ;
626
+ r -> refcount = 1 ;
627
+
628
+ err = block_source_read_block (source , & footer , r -> size ,
629
+ footer_size (r -> version ));
630
+ if (err != footer_size (r -> version )) {
631
+ err = REFTABLE_IO_ERROR ;
632
+ goto done ;
633
+ }
634
+
635
+ err = parse_footer (r , footer .data , header .data );
636
+ if (err )
637
+ goto done ;
638
+
639
+ * out = r ;
640
+
641
+ done :
642
+ reftable_block_done (& footer );
643
+ reftable_block_done (& header );
644
+ if (err ) {
645
+ reftable_free (r );
646
+ block_source_close (source );
650
647
}
651
648
return err ;
652
649
}
653
650
654
- void reftable_reader_free (struct reftable_reader * r )
651
+ void reftable_reader_incref (struct reftable_reader * r )
652
+ {
653
+ if (!r -> refcount )
654
+ BUG ("cannot increment ref counter of dead reader" );
655
+ r -> refcount ++ ;
656
+ }
657
+
658
+ void reftable_reader_decref (struct reftable_reader * r )
655
659
{
656
660
if (!r )
657
661
return ;
658
- reader_close (r );
662
+ if (!r -> refcount )
663
+ BUG ("cannot decrement ref counter of dead reader" );
664
+ if (-- r -> refcount )
665
+ return ;
666
+ block_source_close (& r -> source );
667
+ FREE_AND_NULL (r -> name );
659
668
reftable_free (r );
660
669
}
661
670
@@ -786,7 +795,7 @@ int reftable_reader_print_blocks(const char *tablename)
786
795
if (err < 0 )
787
796
goto done ;
788
797
789
- err = reftable_new_reader (& r , & src , tablename );
798
+ err = reftable_reader_new (& r , & src , tablename );
790
799
if (err < 0 )
791
800
goto done ;
792
801
@@ -817,7 +826,7 @@ int reftable_reader_print_blocks(const char *tablename)
817
826
}
818
827
819
828
done :
820
- reftable_reader_free (r );
829
+ reftable_reader_decref (r );
821
830
table_iter_close (& ti );
822
831
return err ;
823
832
}
0 commit comments