38
#define GRAPH_CHUNKID_OIDFANOUT 0x4f494446 /* "OIDF" */
39
#define GRAPH_CHUNKID_OIDLOOKUP 0x4f49444c /* "OIDL" */
40
#define GRAPH_CHUNKID_DATA 0x43444154 /* "CDAT" */
41
+#define GRAPH_CHUNKID_GENERATION_DATA 0x47444154 /* "GDAT" */
42
+#define GRAPH_CHUNKID_GENERATION_DATA_OVERFLOW 0x47444f56 /* "GDOV" */
43
#define GRAPH_CHUNKID_EXTRAEDGES 0x45444745 /* "EDGE" */
44
#define GRAPH_CHUNKID_BLOOMINDEXES 0x42494458 /* "BIDX" */
45
#define GRAPH_CHUNKID_BLOOMDATA 0x42444154 /* "BDAT" */
46
#define GRAPH_CHUNKID_BASE 0x42415345 /* "BASE" */
45
-#define MAX_NUM_CHUNKS 7
47
+#define MAX_NUM_CHUNKS 9
48
49
#define GRAPH_DATA_WIDTH (the_hash_algo->rawsz + 16)
50
63
#define GRAPH_MIN_SIZE (GRAPH_HEADER_SIZE + 4 * GRAPH_CHUNKLOOKUP_WIDTH \
64
+ GRAPH_FANOUT_SIZE + the_hash_algo->rawsz)
65
66
+#define CORRECTED_COMMIT_DATE_OFFSET_OVERFLOW (1ULL << 31)
67
+
68
/* Remember to update object flag allocation in object.h */
69
#define REACHABLE (1u<<15)
70
398
graph->chunk_commit_data = data + chunk_offset;
399
break;
400
401
+ case GRAPH_CHUNKID_GENERATION_DATA:
402
+ if (graph->chunk_generation_data)
403
+ chunk_repeated = 1;
404
+ else
405
+ graph->chunk_generation_data = data + chunk_offset;
406
+ break;
407
+
408
+ case GRAPH_CHUNKID_GENERATION_DATA_OVERFLOW:
409
+ if (graph->chunk_generation_data_overflow)
410
+ chunk_repeated = 1;
411
+ else
412
+ graph->chunk_generation_data_overflow = data + chunk_offset;
413
+ break;
414
+
415
case GRAPH_CHUNKID_EXTRAEDGES:
416
if (graph->chunk_extra_edges)
417
chunk_repeated = 1;
772
{
773
const unsigned char *commit_data;
774
struct commit_graph_data *graph_data;
757
- uint32_t lex_index;
758
- uint64_t date_high, date_low;
775
+ uint32_t lex_index, offset_pos;
776
+ uint64_t date_high, date_low, offset;
777
778
while (pos < g->num_commits_in_base)
779
g = g->base_graph;
791
date_low = get_be32(commit_data + g->hash_len + 12);
792
item->date = (timestamp_t)((date_high << 32) | date_low);
793
776
- graph_data->generation = get_be32(commit_data + g->hash_len + 8) >> 2;
794
+ if (g->chunk_generation_data) {
795
+ offset = (timestamp_t)get_be32(g->chunk_generation_data + sizeof(uint32_t) * lex_index);
796
+
797
+ if (offset & CORRECTED_COMMIT_DATE_OFFSET_OVERFLOW) {
798
+ if (!g->chunk_generation_data_overflow)
799
+ die(_("commit-graph requires overflow generation data but has none"));
800
+
801
+ offset_pos = offset ^ CORRECTED_COMMIT_DATE_OFFSET_OVERFLOW;
802
+ graph_data->generation = get_be64(g->chunk_generation_data_overflow + 8 * offset_pos);
803
+ } else
804
+ graph_data->generation = item->date + offset;
805
+ } else
806
+ graph_data->generation = get_be32(commit_data + g->hash_len + 8) >> 2;
807
808
if (g->topo_levels)
809
*topo_level_slab_at(g->topo_levels, item) = get_be32(commit_data + g->hash_len + 8) >> 2;
975
struct oid_array oids;
976
struct packed_commit_list commits;
977
int num_extra_edges;
978
+ int num_generation_data_overflows;
979
unsigned long approx_nr_objects;
980
struct progress *progress;
981
int progress_done;
994
report_progress:1,
995
split:1,
996
changed_paths:1,
966
- order_by_pack:1;
997
+ order_by_pack:1,
998
+ write_generation_data:1;
999
1000
struct topo_level_slab *topo_levels;
1001
const struct commit_graph_opts *opts;
1155
return 0;
1156
}
1157
1158
+static int write_graph_chunk_generation_data(struct hashfile *f,
1159
+ struct write_commit_graph_context *ctx)
1160
+{
1161
+ int i, num_generation_data_overflows = 0;
1162
+
1163
+ for (i = 0; i < ctx->commits.nr; i++) {
1164
+ struct commit *c = ctx->commits.list[i];
1165
+ timestamp_t offset = commit_graph_data_at(c)->generation - c->date;
1166
+ display_progress(ctx->progress, ++ctx->progress_cnt);
1167
+
1168
+ if (offset > GENERATION_NUMBER_V2_OFFSET_MAX) {
1169
+ offset = CORRECTED_COMMIT_DATE_OFFSET_OVERFLOW | num_generation_data_overflows;
1170
+ num_generation_data_overflows++;
1171
+ }
1172
+
1173
+ hashwrite_be32(f, offset);
1174
+ }
1175
+
1176
+ return 0;
1177
+}
1178
+
1179
+static int write_graph_chunk_generation_data_overflow(struct hashfile *f,
1180
+ struct write_commit_graph_context *ctx)
1181
+{
1182
+ int i;
1183
+ for (i = 0; i < ctx->commits.nr; i++) {
1184
+ struct commit *c = ctx->commits.list[i];
1185
+ timestamp_t offset = commit_graph_data_at(c)->generation - c->date;
1186
+ display_progress(ctx->progress, ++ctx->progress_cnt);
1187
+
1188
+ if (offset > GENERATION_NUMBER_V2_OFFSET_MAX) {
1189
+ hashwrite_be32(f, offset >> 32);
1190
+ hashwrite_be32(f, (uint32_t) offset);
1191
+ }
1192
+ }
1193
+
1194
+ return 0;
1195
+}
1196
+
1197
static int write_graph_chunk_extra_edges(struct hashfile *f,
1198
struct write_commit_graph_context *ctx)
1199
{
1457
if (current->date && current->date > max_corrected_commit_date)
1458
max_corrected_commit_date = current->date - 1;
1459
commit_graph_data_at(current)->generation = max_corrected_commit_date + 1;
1460
+
1461
+ if (commit_graph_data_at(current)->generation - current->date > GENERATION_NUMBER_V2_OFFSET_MAX)
1462
+ ctx->num_generation_data_overflows++;
1463
}
1464
}
1465
}
1793
chunks[2].id = GRAPH_CHUNKID_DATA;
1794
chunks[2].size = (hashsz + 16) * ctx->commits.nr;
1795
chunks[2].write_fn = write_graph_chunk_data;
1796
+
1797
+ if (git_env_bool(GIT_TEST_COMMIT_GRAPH_NO_GDAT, 0))
1798
+ ctx->write_generation_data = 0;
1799
+ if (ctx->write_generation_data) {
1800
+ chunks[num_chunks].id = GRAPH_CHUNKID_GENERATION_DATA;
1801
+ chunks[num_chunks].size = sizeof(uint32_t) * ctx->commits.nr;
1802
+ chunks[num_chunks].write_fn = write_graph_chunk_generation_data;
1803
+ num_chunks++;
1804
+ }
1805
+ if (ctx->num_generation_data_overflows) {
1806
+ chunks[num_chunks].id = GRAPH_CHUNKID_GENERATION_DATA_OVERFLOW;
1807
+ chunks[num_chunks].size = sizeof(timestamp_t) * ctx->num_generation_data_overflows;
1808
+ chunks[num_chunks].write_fn = write_graph_chunk_generation_data_overflow;
1809
+ num_chunks++;
1810
+ }
1811
if (ctx->num_extra_edges) {
1812
chunks[num_chunks].id = GRAPH_CHUNKID_EXTRAEDGES;
1813
chunks[num_chunks].size = 4 * ctx->num_extra_edges;
2228
ctx->split = flags & COMMIT_GRAPH_WRITE_SPLIT ? 1 : 0;
2229
ctx->opts = opts;
2230
ctx->total_bloom_filter_data_size = 0;
2231
+ ctx->write_generation_data = 1;
2232
+ ctx->num_generation_data_overflows = 0;
2233
2234
bloom_settings.bits_per_entry = git_env_ulong("GIT_TEST_BLOOM_SETTINGS_BITS_PER_ENTRY",
2235
bloom_settings.bits_per_entry);
2536
continue;
2537
2538
/*
2448
- * If one of our parents has generation GENERATION_NUMBER_V1_MAX, then
2449
- * our generation is also GENERATION_NUMBER_V1_MAX. Decrement to avoid
2450
- * extra logic in the following condition.
2539
+ * If we are using topological level and one of our parents has
2540
+ * generation GENERATION_NUMBER_V1_MAX, then our generation is
2541
+ * also GENERATION_NUMBER_V1_MAX. Decrement to avoid extra logic
2542
+ * in the following condition.
2543
*/
2452
- if (max_generation == GENERATION_NUMBER_V1_MAX)
2544
+ if (!g->chunk_generation_data && max_generation == GENERATION_NUMBER_V1_MAX)
2545
max_generation--;
2546
2547
generation = commit_graph_generation(graph_commit);
2456
- if (generation != max_generation + 1)
2457
- graph_report(_("commit-graph generation for commit %s is %"PRItime" != %"PRItime),
2548
+ if (generation < max_generation + 1)
2549
+ graph_report(_("commit-graph generation for commit %s is %"PRItime" < %"PRItime),
2550
oid_to_hex(&cur_oid),
2551
generation,
2552
max_generation + 1);