6
* https://developers.google.com/open-source/licenses/bsd
7
*/
8
9
-#include "reader.h"
9
+#include "table.h"
10
11
#include "system.h"
12
#include "block.h"
39
source->ops = NULL;
40
}
41
42
-static struct reftable_reader_offsets *
43
-reader_offsets_for(struct reftable_reader *r, uint8_t typ)
42
+static struct reftable_table_offsets *
43
+table_offsets_for(struct reftable_table *t, uint8_t typ)
44
{
45
switch (typ) {
46
case BLOCK_TYPE_REF:
47
- return &r->ref_offsets;
47
+ return &t->ref_offsets;
48
case BLOCK_TYPE_LOG:
49
- return &r->log_offsets;
49
+ return &t->log_offsets;
50
case BLOCK_TYPE_OBJ:
51
- return &r->obj_offsets;
51
+ return &t->obj_offsets;
52
}
53
abort();
54
}
55
56
-static int reader_get_block(struct reftable_reader *r,
57
- struct reftable_block *dest, uint64_t off,
58
- uint32_t sz)
56
+static int table_get_block(struct reftable_table *t,
57
+ struct reftable_block *dest, uint64_t off,
58
+ uint32_t sz)
59
{
60
ssize_t bytes_read;
61
- if (off >= r->size)
61
+ if (off >= t->size)
62
return 0;
63
- if (off + sz > r->size)
64
- sz = r->size - off;
63
+ if (off + sz > t->size)
64
+ sz = t->size - off;
65
66
- bytes_read = block_source_read_block(&r->source, dest, off, sz);
66
+ bytes_read = block_source_read_block(&t->source, dest, off, sz);
67
if (bytes_read < 0)
68
return (int)bytes_read;
69
70
return 0;
71
}
72
73
-enum reftable_hash reftable_reader_hash_id(struct reftable_reader *r)
73
+enum reftable_hash reftable_table_hash_id(struct reftable_table *t)
74
{
75
- return r->hash_id;
75
+ return t->hash_id;
76
}
77
78
-const char *reader_name(struct reftable_reader *r)
78
+const char *reftable_table_name(struct reftable_table *t)
79
{
80
- return r->name;
80
+ return t->name;
81
}
82
83
-static int parse_footer(struct reftable_reader *r, uint8_t *footer,
83
+static int parse_footer(struct reftable_table *t, uint8_t *footer,
84
uint8_t *header)
85
{
86
uint8_t *f = footer;
95
}
96
f += 4;
97
98
- if (memcmp(footer, header, header_size(r->version))) {
98
+ if (memcmp(footer, header, header_size(t->version))) {
99
err = REFTABLE_FORMAT_ERROR;
100
goto done;
101
}
102
103
f++;
104
- r->block_size = reftable_get_be24(f);
104
+ t->block_size = reftable_get_be24(f);
105
106
f += 3;
107
- r->min_update_index = reftable_get_be64(f);
107
+ t->min_update_index = reftable_get_be64(f);
108
f += 8;
109
- r->max_update_index = reftable_get_be64(f);
109
+ t->max_update_index = reftable_get_be64(f);
110
f += 8;
111
112
- if (r->version == 1) {
113
- r->hash_id = REFTABLE_HASH_SHA1;
112
+ if (t->version == 1) {
113
+ t->hash_id = REFTABLE_HASH_SHA1;
114
} else {
115
switch (reftable_get_be32(f)) {
116
case REFTABLE_FORMAT_ID_SHA1:
117
- r->hash_id = REFTABLE_HASH_SHA1;
117
+ t->hash_id = REFTABLE_HASH_SHA1;
118
break;
119
case REFTABLE_FORMAT_ID_SHA256:
120
- r->hash_id = REFTABLE_HASH_SHA256;
120
+ t->hash_id = REFTABLE_HASH_SHA256;
121
break;
122
default:
123
err = REFTABLE_FORMAT_ERROR;
127
f += 4;
128
}
129
130
- r->ref_offsets.index_offset = reftable_get_be64(f);
130
+ t->ref_offsets.index_offset = reftable_get_be64(f);
131
f += 8;
132
133
- r->obj_offsets.offset = reftable_get_be64(f);
133
+ t->obj_offsets.offset = reftable_get_be64(f);
134
f += 8;
135
136
- r->object_id_len = r->obj_offsets.offset & ((1 << 5) - 1);
137
- r->obj_offsets.offset >>= 5;
136
+ t->object_id_len = t->obj_offsets.offset & ((1 << 5) - 1);
137
+ t->obj_offsets.offset >>= 5;
138
139
- r->obj_offsets.index_offset = reftable_get_be64(f);
139
+ t->obj_offsets.index_offset = reftable_get_be64(f);
140
f += 8;
141
- r->log_offsets.offset = reftable_get_be64(f);
141
+ t->log_offsets.offset = reftable_get_be64(f);
142
f += 8;
143
- r->log_offsets.index_offset = reftable_get_be64(f);
143
+ t->log_offsets.index_offset = reftable_get_be64(f);
144
f += 8;
145
146
computed_crc = crc32(0, footer, f - footer);
151
goto done;
152
}
153
154
- first_block_typ = header[header_size(r->version)];
155
- r->ref_offsets.is_present = (first_block_typ == BLOCK_TYPE_REF);
156
- r->ref_offsets.offset = 0;
157
- r->log_offsets.is_present = (first_block_typ == BLOCK_TYPE_LOG ||
158
- r->log_offsets.offset > 0);
159
- r->obj_offsets.is_present = r->obj_offsets.offset > 0;
160
- if (r->obj_offsets.is_present && !r->object_id_len) {
154
+ first_block_typ = header[header_size(t->version)];
155
+ t->ref_offsets.is_present = (first_block_typ == BLOCK_TYPE_REF);
156
+ t->ref_offsets.offset = 0;
157
+ t->log_offsets.is_present = (first_block_typ == BLOCK_TYPE_LOG ||
158
+ t->log_offsets.offset > 0);
159
+ t->obj_offsets.is_present = t->obj_offsets.offset > 0;
160
+ if (t->obj_offsets.is_present && !t->object_id_len) {
161
err = REFTABLE_FORMAT_ERROR;
162
goto done;
163
}
168
}
169
170
struct table_iter {
171
- struct reftable_reader *r;
171
+ struct reftable_table *table;
172
uint8_t typ;
173
uint64_t block_off;
174
struct block_reader br;
176
int is_finished;
177
};
178
179
-static int table_iter_init(struct table_iter *ti, struct reftable_reader *r)
179
+static int table_iter_init(struct table_iter *ti, struct reftable_table *t)
180
{
181
struct block_iter bi = BLOCK_ITER_INIT;
182
memset(ti, 0, sizeof(*ti));
183
- reftable_reader_incref(r);
184
- ti->r = r;
183
+ reftable_table_incref(t);
184
+ ti->table = t;
185
ti->bi = bi;
186
return 0;
187
}
191
{
192
int res = block_iter_next(&ti->bi, rec);
193
if (res == 0 && reftable_record_type(rec) == BLOCK_TYPE_REF) {
194
- rec->u.ref.update_index += ti->r->min_update_index;
194
+ rec->u.ref.update_index += ti->table->min_update_index;
195
}
196
197
return res;
219
return result;
220
}
221
222
-int reader_init_block_reader(struct reftable_reader *r, struct block_reader *br,
223
- uint64_t next_off, uint8_t want_typ)
222
+int table_init_block_reader(struct reftable_table *t, struct block_reader *br,
223
+ uint64_t next_off, uint8_t want_typ)
224
{
225
- int32_t guess_block_size = r->block_size ? r->block_size :
225
+ int32_t guess_block_size = t->block_size ? t->block_size :
226
DEFAULT_BLOCK_SIZE;
227
struct reftable_block block = { NULL };
228
uint8_t block_typ = 0;
229
int err = 0;
230
- uint32_t header_off = next_off ? 0 : header_size(r->version);
230
+ uint32_t header_off = next_off ? 0 : header_size(t->version);
231
int32_t block_size = 0;
232
233
- if (next_off >= r->size)
233
+ if (next_off >= t->size)
234
return 1;
235
236
- err = reader_get_block(r, &block, next_off, guess_block_size);
236
+ err = table_get_block(t, &block, next_off, guess_block_size);
237
if (err < 0)
238
goto done;
239
240
block_size = extract_block_size(block.data, &block_typ, next_off,
241
- r->version);
241
+ t->version);
242
if (block_size < 0) {
243
err = block_size;
244
goto done;
250
251
if (block_size > guess_block_size) {
252
reftable_block_done(&block);
253
- err = reader_get_block(r, &block, next_off, block_size);
253
+ err = table_get_block(t, &block, next_off, block_size);
254
if (err < 0) {
255
goto done;
256
}
257
}
258
259
- err = block_reader_init(br, &block, header_off, r->block_size,
260
- hash_size(r->hash_id));
259
+ err = block_reader_init(br, &block, header_off, t->block_size,
260
+ hash_size(t->hash_id));
261
done:
262
reftable_block_done(&block);
263
268
{
269
table_iter_block_done(ti);
270
block_iter_close(&ti->bi);
271
- reftable_reader_decref(ti->r);
271
+ reftable_table_decref(ti->table);
272
}
273
274
static int table_iter_next_block(struct table_iter *ti)
276
uint64_t next_block_off = ti->block_off + ti->br.full_block_size;
277
int err;
278
279
- err = reader_init_block_reader(ti->r, &ti->br, next_block_off, ti->typ);
279
+ err = table_init_block_reader(ti->table, &ti->br, next_block_off, ti->typ);
280
if (err > 0)
281
ti->is_finished = 1;
282
if (err)
326
{
327
int err;
328
329
- err = reader_init_block_reader(ti->r, &ti->br, off, typ);
329
+ err = table_init_block_reader(ti->table, &ti->br, off, typ);
330
if (err != 0)
331
return err;
332
339
340
static int table_iter_seek_start(struct table_iter *ti, uint8_t typ, int index)
341
{
342
- struct reftable_reader_offsets *offs = reader_offsets_for(ti->r, typ);
342
+ struct reftable_table_offsets *offs = table_offsets_for(ti->table, typ);
343
uint64_t off = offs->offset;
344
if (index) {
345
off = offs->index_offset;
518
struct reftable_record *want)
519
{
520
uint8_t typ = reftable_record_type(want);
521
- struct reftable_reader_offsets *offs = reader_offsets_for(ti->r, typ);
521
+ struct reftable_table_offsets *offs = table_offsets_for(ti->table, typ);
522
int err;
523
524
err = table_iter_seek_start(ti, reftable_record_type(want),
566
it->ops = &table_iter_vtable;
567
}
568
569
-int reader_init_iter(struct reftable_reader *r,
570
- struct reftable_iterator *it,
571
- uint8_t typ)
569
+int table_init_iter(struct reftable_table *t,
570
+ struct reftable_iterator *it,
571
+ uint8_t typ)
572
{
573
- struct reftable_reader_offsets *offs = reader_offsets_for(r, typ);
573
+ struct reftable_table_offsets *offs = table_offsets_for(t, typ);
574
575
if (offs->is_present) {
576
struct table_iter *ti;
578
if (!ti)
579
return REFTABLE_OUT_OF_MEMORY_ERROR;
580
581
- table_iter_init(ti, r);
581
+ table_iter_init(ti, t);
582
iterator_from_table_iter(it, ti);
583
} else {
584
iterator_set_empty(it);
587
return 0;
588
}
589
590
-int reftable_reader_init_ref_iterator(struct reftable_reader *r,
591
- struct reftable_iterator *it)
590
+int reftable_table_init_ref_iterator(struct reftable_table *t,
591
+ struct reftable_iterator *it)
592
{
593
- return reader_init_iter(r, it, BLOCK_TYPE_REF);
593
+ return table_init_iter(t, it, BLOCK_TYPE_REF);
594
}
595
596
-int reftable_reader_init_log_iterator(struct reftable_reader *r,
597
- struct reftable_iterator *it)
596
+int reftable_table_init_log_iterator(struct reftable_table *t,
597
+ struct reftable_iterator *it)
598
{
599
- return reader_init_iter(r, it, BLOCK_TYPE_LOG);
599
+ return table_init_iter(t, it, BLOCK_TYPE_LOG);
600
}
601
602
-int reftable_reader_new(struct reftable_reader **out,
603
- struct reftable_block_source *source, char const *name)
602
+int reftable_table_new(struct reftable_table **out,
603
+ struct reftable_block_source *source, char const *name)
604
{
605
struct reftable_block footer = { 0 };
606
struct reftable_block header = { 0 };
607
- struct reftable_reader *r;
607
+ struct reftable_table *t;
608
uint64_t file_size = block_source_size(source);
609
uint32_t read_size;
610
ssize_t bytes_read;
611
int err;
612
613
- REFTABLE_CALLOC_ARRAY(r, 1);
614
- if (!r) {
613
+ REFTABLE_CALLOC_ARRAY(t, 1);
614
+ if (!t) {
615
err = REFTABLE_OUT_OF_MEMORY_ERROR;
616
goto done;
617
}
636
err = REFTABLE_FORMAT_ERROR;
637
goto done;
638
}
639
- r->version = header.data[4];
640
- if (r->version != 1 && r->version != 2) {
639
+ t->version = header.data[4];
640
+ if (t->version != 1 && t->version != 2) {
641
err = REFTABLE_FORMAT_ERROR;
642
goto done;
643
}
644
645
- r->size = file_size - footer_size(r->version);
646
- r->source = *source;
647
- r->name = reftable_strdup(name);
648
- if (!r->name) {
645
+ t->size = file_size - footer_size(t->version);
646
+ t->source = *source;
647
+ t->name = reftable_strdup(name);
648
+ if (!t->name) {
649
err = REFTABLE_OUT_OF_MEMORY_ERROR;
650
goto done;
651
}
652
- r->hash_id = 0;
653
- r->refcount = 1;
652
+ t->hash_id = 0;
653
+ t->refcount = 1;
654
655
- bytes_read = block_source_read_block(source, &footer, r->size,
656
- footer_size(r->version));
657
- if (bytes_read < 0 || (size_t)bytes_read != footer_size(r->version)) {
655
+ bytes_read = block_source_read_block(source, &footer, t->size,
656
+ footer_size(t->version));
657
+ if (bytes_read < 0 || (size_t)bytes_read != footer_size(t->version)) {
658
err = REFTABLE_IO_ERROR;
659
goto done;
660
}
661
662
- err = parse_footer(r, footer.data, header.data);
662
+ err = parse_footer(t, footer.data, header.data);
663
if (err)
664
goto done;
665
666
- *out = r;
666
+ *out = t;
667
668
done:
669
reftable_block_done(&footer);
670
reftable_block_done(&header);
671
if (err) {
672
- if (r)
673
- reftable_free(r->name);
674
- reftable_free(r);
672
+ if (t)
673
+ reftable_free(t->name);
674
+ reftable_free(t);
675
block_source_close(source);
676
}
677
return err;
678
}
679
680
-void reftable_reader_incref(struct reftable_reader *r)
680
+void reftable_table_incref(struct reftable_table *t)
681
{
682
- r->refcount++;
682
+ t->refcount++;
683
}
684
685
-void reftable_reader_decref(struct reftable_reader *r)
685
+void reftable_table_decref(struct reftable_table *t)
686
{
687
- if (!r)
687
+ if (!t)
688
return;
689
- if (--r->refcount)
689
+ if (--t->refcount)
690
return;
691
- block_source_close(&r->source);
692
- REFTABLE_FREE_AND_NULL(r->name);
693
- reftable_free(r);
691
+ block_source_close(&t->source);
692
+ REFTABLE_FREE_AND_NULL(t->name);
693
+ reftable_free(t);
694
}
695
696
-static int reftable_reader_refs_for_indexed(struct reftable_reader *r,
697
- struct reftable_iterator *it,
698
- uint8_t *oid)
696
+static int reftable_table_refs_for_indexed(struct reftable_table *t,
697
+ struct reftable_iterator *it,
698
+ uint8_t *oid)
699
{
700
struct reftable_record want = {
701
.type = BLOCK_TYPE_OBJ,
702
.u.obj = {
703
.hash_prefix = oid,
704
- .hash_prefix_len = r->object_id_len,
704
+ .hash_prefix_len = t->object_id_len,
705
},
706
};
707
struct reftable_iterator oit = { NULL };
713
struct indexed_table_ref_iter *itr = NULL;
714
715
/* Look through the reverse index. */
716
- err = reader_init_iter(r, &oit, BLOCK_TYPE_OBJ);
716
+ err = table_init_iter(t, &oit, BLOCK_TYPE_OBJ);
717
if (err < 0)
718
goto done;
719
727
goto done;
728
729
if (err > 0 || memcmp(want.u.obj.hash_prefix, got.u.obj.hash_prefix,
730
- r->object_id_len)) {
730
+ t->object_id_len)) {
731
/* didn't find it; return empty iterator */
732
iterator_set_empty(it);
733
err = 0;
734
goto done;
735
}
736
737
- err = indexed_table_ref_iter_new(&itr, r, oid, hash_size(r->hash_id),
737
+ err = indexed_table_ref_iter_new(&itr, t, oid, hash_size(t->hash_id),
738
got.u.obj.offsets,
739
got.u.obj.offset_len);
740
if (err < 0)
748
return err;
749
}
750
751
-static int reftable_reader_refs_for_unindexed(struct reftable_reader *r,
752
- struct reftable_iterator *it,
753
- uint8_t *oid)
751
+static int reftable_table_refs_for_unindexed(struct reftable_table *t,
752
+ struct reftable_iterator *it,
753
+ uint8_t *oid)
754
{
755
struct table_iter *ti;
756
struct filtering_ref_iterator *filter = NULL;
757
struct filtering_ref_iterator empty = FILTERING_REF_ITERATOR_INIT;
758
- uint32_t oid_len = hash_size(r->hash_id);
758
+ uint32_t oid_len = hash_size(t->hash_id);
759
int err;
760
761
REFTABLE_ALLOC_ARRAY(ti, 1);
764
goto out;
765
}
766
767
- table_iter_init(ti, r);
767
+ table_iter_init(ti, t);
768
err = table_iter_seek_start(ti, BLOCK_TYPE_REF, 0);
769
if (err < 0)
770
goto out;
795
return err;
796
}
797
798
-int reftable_reader_refs_for(struct reftable_reader *r,
799
- struct reftable_iterator *it, uint8_t *oid)
798
+int reftable_table_refs_for(struct reftable_table *t,
799
+ struct reftable_iterator *it, uint8_t *oid)
800
{
801
- if (r->obj_offsets.is_present)
802
- return reftable_reader_refs_for_indexed(r, it, oid);
803
- return reftable_reader_refs_for_unindexed(r, it, oid);
801
+ if (t->obj_offsets.is_present)
802
+ return reftable_table_refs_for_indexed(t, it, oid);
803
+ return reftable_table_refs_for_unindexed(t, it, oid);
804
}
805
806
-uint64_t reftable_reader_max_update_index(struct reftable_reader *r)
806
+uint64_t reftable_table_max_update_index(struct reftable_table *t)
807
{
808
- return r->max_update_index;
808
+ return t->max_update_index;
809
}
810
811
-uint64_t reftable_reader_min_update_index(struct reftable_reader *r)
811
+uint64_t reftable_table_min_update_index(struct reftable_table *t)
812
{
813
- return r->min_update_index;
813
+ return t->min_update_index;
814
}
815
816
-int reftable_reader_print_blocks(const char *tablename)
816
+int reftable_table_print_blocks(const char *tablename)
817
{
818
struct {
819
const char *name;
833
},
834
};
835
struct reftable_block_source src = { 0 };
836
- struct reftable_reader *r = NULL;
836
+ struct reftable_table *table = NULL;
837
struct table_iter ti = { 0 };
838
size_t i;
839
int err;
842
if (err < 0)
843
goto done;
844
845
- err = reftable_reader_new(&r, &src, tablename);
845
+ err = reftable_table_new(&table, &src, tablename);
846
if (err < 0)
847
goto done;
848
849
- table_iter_init(&ti, r);
849
+ table_iter_init(&ti, table);
850
851
printf("header:\n");
852
- printf(" block_size: %d\n", r->block_size);
852
+ printf(" block_size: %d\n", table->block_size);
853
854
for (i = 0; i < sizeof(sections) / sizeof(*sections); i++) {
855
err = table_iter_seek_start(&ti, sections[i].type, 0);
873
}
874
875
done:
876
- reftable_reader_decref(r);
876
+ reftable_table_decref(table);
877
table_iter_close(&ti);
878
return err;
879
}