17
17
#include "bloom.h"
18
18
#include "commit-slab.h"
19
19
#include "shallow.h"
20
+ #include "json-writer.h"
21
+ #include "trace2.h"
20
22
21
23
void git_test_write_commit_graph_or_die (void )
22
24
{
@@ -617,10 +619,6 @@ static int prepare_commit_graph(struct repository *r)
617
619
return !!r -> objects -> commit_graph ;
618
620
r -> objects -> commit_graph_attempted = 1 ;
619
621
620
- if (git_env_bool (GIT_TEST_COMMIT_GRAPH_DIE_ON_LOAD , 0 ))
621
- die ("dying as requested by the '%s' variable on commit-graph load!" ,
622
- GIT_TEST_COMMIT_GRAPH_DIE_ON_LOAD );
623
-
624
622
prepare_repo_settings (r );
625
623
626
624
if (!git_env_bool (GIT_TEST_COMMIT_GRAPH , 0 ) &&
@@ -849,6 +847,14 @@ static int parse_commit_in_graph_one(struct repository *r,
849
847
850
848
int parse_commit_in_graph (struct repository * r , struct commit * item )
851
849
{
850
+ static int checked_env = 0 ;
851
+
852
+ if (!checked_env &&
853
+ git_env_bool (GIT_TEST_COMMIT_GRAPH_DIE_ON_PARSE , 0 ))
854
+ die ("dying as requested by the '%s' variable on commit-graph parse!" ,
855
+ GIT_TEST_COMMIT_GRAPH_DIE_ON_PARSE );
856
+ checked_env = 1 ;
857
+
852
858
if (!prepare_commit_graph (r ))
853
859
return 0 ;
854
860
return parse_commit_in_graph_one (r , r -> objects -> commit_graph , item );
@@ -941,10 +947,11 @@ struct write_commit_graph_context {
941
947
942
948
const struct split_commit_graph_opts * split_opts ;
943
949
size_t total_bloom_filter_data_size ;
950
+ const struct bloom_filter_settings * bloom_settings ;
944
951
};
945
952
946
- static void write_graph_chunk_fanout (struct hashfile * f ,
947
- struct write_commit_graph_context * ctx )
953
+ static int write_graph_chunk_fanout (struct hashfile * f ,
954
+ struct write_commit_graph_context * ctx )
948
955
{
949
956
int i , count = 0 ;
950
957
struct commit * * list = ctx -> commits .list ;
@@ -965,17 +972,21 @@ static void write_graph_chunk_fanout(struct hashfile *f,
965
972
966
973
hashwrite_be32 (f , count );
967
974
}
975
+
976
+ return 0 ;
968
977
}
969
978
970
- static void write_graph_chunk_oids (struct hashfile * f , int hash_len ,
971
- struct write_commit_graph_context * ctx )
979
+ static int write_graph_chunk_oids (struct hashfile * f ,
980
+ struct write_commit_graph_context * ctx )
972
981
{
973
982
struct commit * * list = ctx -> commits .list ;
974
983
int count ;
975
984
for (count = 0 ; count < ctx -> commits .nr ; count ++ , list ++ ) {
976
985
display_progress (ctx -> progress , ++ ctx -> progress_cnt );
977
- hashwrite (f , (* list )-> object .oid .hash , ( int ) hash_len );
986
+ hashwrite (f , (* list )-> object .oid .hash , the_hash_algo -> rawsz );
978
987
}
988
+
989
+ return 0 ;
979
990
}
980
991
981
992
static const unsigned char * commit_to_sha1 (size_t index , void * table )
@@ -984,8 +995,8 @@ static const unsigned char *commit_to_sha1(size_t index, void *table)
984
995
return commits [index ]-> object .oid .hash ;
985
996
}
986
997
987
- static void write_graph_chunk_data (struct hashfile * f , int hash_len ,
988
- struct write_commit_graph_context * ctx )
998
+ static int write_graph_chunk_data (struct hashfile * f ,
999
+ struct write_commit_graph_context * ctx )
989
1000
{
990
1001
struct commit * * list = ctx -> commits .list ;
991
1002
struct commit * * last = ctx -> commits .list + ctx -> commits .nr ;
@@ -1002,7 +1013,7 @@ static void write_graph_chunk_data(struct hashfile *f, int hash_len,
1002
1013
die (_ ("unable to parse commit %s" ),
1003
1014
oid_to_hex (& (* list )-> object .oid ));
1004
1015
tree = get_commit_tree_oid (* list );
1005
- hashwrite (f , tree -> hash , hash_len );
1016
+ hashwrite (f , tree -> hash , the_hash_algo -> rawsz );
1006
1017
1007
1018
parent = (* list )-> parents ;
1008
1019
@@ -1082,10 +1093,12 @@ static void write_graph_chunk_data(struct hashfile *f, int hash_len,
1082
1093
1083
1094
list ++ ;
1084
1095
}
1096
+
1097
+ return 0 ;
1085
1098
}
1086
1099
1087
- static void write_graph_chunk_extra_edges (struct hashfile * f ,
1088
- struct write_commit_graph_context * ctx )
1100
+ static int write_graph_chunk_extra_edges (struct hashfile * f ,
1101
+ struct write_commit_graph_context * ctx )
1089
1102
{
1090
1103
struct commit * * list = ctx -> commits .list ;
1091
1104
struct commit * * last = ctx -> commits .list + ctx -> commits .nr ;
@@ -1134,41 +1147,67 @@ static void write_graph_chunk_extra_edges(struct hashfile *f,
1134
1147
1135
1148
list ++ ;
1136
1149
}
1150
+
1151
+ return 0 ;
1137
1152
}
1138
1153
1139
- static void write_graph_chunk_bloom_indexes (struct hashfile * f ,
1140
- struct write_commit_graph_context * ctx )
1154
+ static int write_graph_chunk_bloom_indexes (struct hashfile * f ,
1155
+ struct write_commit_graph_context * ctx )
1141
1156
{
1142
1157
struct commit * * list = ctx -> commits .list ;
1143
1158
struct commit * * last = ctx -> commits .list + ctx -> commits .nr ;
1144
1159
uint32_t cur_pos = 0 ;
1145
1160
1146
1161
while (list < last ) {
1147
1162
struct bloom_filter * filter = get_bloom_filter (ctx -> r , * list , 0 );
1148
- cur_pos += filter -> len ;
1163
+ size_t len = filter ? filter -> len : 0 ;
1164
+ cur_pos += len ;
1149
1165
display_progress (ctx -> progress , ++ ctx -> progress_cnt );
1150
1166
hashwrite_be32 (f , cur_pos );
1151
1167
list ++ ;
1152
1168
}
1169
+
1170
+ return 0 ;
1153
1171
}
1154
1172
1155
- static void write_graph_chunk_bloom_data (struct hashfile * f ,
1156
- struct write_commit_graph_context * ctx ,
1157
- const struct bloom_filter_settings * settings )
1173
+ static void trace2_bloom_filter_settings (struct write_commit_graph_context * ctx )
1174
+ {
1175
+ struct json_writer jw = JSON_WRITER_INIT ;
1176
+
1177
+ jw_object_begin (& jw , 0 );
1178
+ jw_object_intmax (& jw , "hash_version" , ctx -> bloom_settings -> hash_version );
1179
+ jw_object_intmax (& jw , "num_hashes" , ctx -> bloom_settings -> num_hashes );
1180
+ jw_object_intmax (& jw , "bits_per_entry" , ctx -> bloom_settings -> bits_per_entry );
1181
+ jw_end (& jw );
1182
+
1183
+ trace2_data_json ("bloom" , ctx -> r , "settings" , & jw );
1184
+
1185
+ jw_release (& jw );
1186
+ }
1187
+
1188
+ static int write_graph_chunk_bloom_data (struct hashfile * f ,
1189
+ struct write_commit_graph_context * ctx )
1158
1190
{
1159
1191
struct commit * * list = ctx -> commits .list ;
1160
1192
struct commit * * last = ctx -> commits .list + ctx -> commits .nr ;
1161
1193
1162
- hashwrite_be32 (f , settings -> hash_version );
1163
- hashwrite_be32 (f , settings -> num_hashes );
1164
- hashwrite_be32 (f , settings -> bits_per_entry );
1194
+ trace2_bloom_filter_settings (ctx );
1195
+
1196
+ hashwrite_be32 (f , ctx -> bloom_settings -> hash_version );
1197
+ hashwrite_be32 (f , ctx -> bloom_settings -> num_hashes );
1198
+ hashwrite_be32 (f , ctx -> bloom_settings -> bits_per_entry );
1165
1199
1166
1200
while (list < last ) {
1167
1201
struct bloom_filter * filter = get_bloom_filter (ctx -> r , * list , 0 );
1202
+ size_t len = filter ? filter -> len : 0 ;
1203
+
1168
1204
display_progress (ctx -> progress , ++ ctx -> progress_cnt );
1169
- hashwrite (f , filter -> data , filter -> len * sizeof (unsigned char ));
1205
+ if (len )
1206
+ hashwrite (f , filter -> data , len * sizeof (unsigned char ));
1170
1207
list ++ ;
1171
1208
}
1209
+
1210
+ return 0 ;
1172
1211
}
1173
1212
1174
1213
static int oid_compare (const void * _a , const void * _b )
@@ -1579,9 +1618,13 @@ static int write_graph_chunk_base(struct hashfile *f,
1579
1618
return 0 ;
1580
1619
}
1581
1620
1621
+ typedef int (* chunk_write_fn )(struct hashfile * f ,
1622
+ struct write_commit_graph_context * ctx );
1623
+
1582
1624
struct chunk_info {
1583
1625
uint32_t id ;
1584
1626
uint64_t size ;
1627
+ chunk_write_fn write_fn ;
1585
1628
};
1586
1629
1587
1630
static int write_commit_graph_file (struct write_commit_graph_context * ctx )
@@ -1596,7 +1639,15 @@ static int write_commit_graph_file(struct write_commit_graph_context *ctx)
1596
1639
int num_chunks = 3 ;
1597
1640
uint64_t chunk_offset ;
1598
1641
struct object_id file_hash ;
1599
- const struct bloom_filter_settings bloom_settings = DEFAULT_BLOOM_FILTER_SETTINGS ;
1642
+ struct bloom_filter_settings bloom_settings = DEFAULT_BLOOM_FILTER_SETTINGS ;
1643
+
1644
+ if (!ctx -> bloom_settings ) {
1645
+ bloom_settings .bits_per_entry = git_env_ulong ("GIT_TEST_BLOOM_SETTINGS_BITS_PER_ENTRY" ,
1646
+ bloom_settings .bits_per_entry );
1647
+ bloom_settings .num_hashes = git_env_ulong ("GIT_TEST_BLOOM_SETTINGS_NUM_HASHES" ,
1648
+ bloom_settings .num_hashes );
1649
+ ctx -> bloom_settings = & bloom_settings ;
1650
+ }
1600
1651
1601
1652
if (ctx -> split ) {
1602
1653
struct strbuf tmp_file = STRBUF_INIT ;
@@ -1644,27 +1695,34 @@ static int write_commit_graph_file(struct write_commit_graph_context *ctx)
1644
1695
1645
1696
chunks [0 ].id = GRAPH_CHUNKID_OIDFANOUT ;
1646
1697
chunks [0 ].size = GRAPH_FANOUT_SIZE ;
1698
+ chunks [0 ].write_fn = write_graph_chunk_fanout ;
1647
1699
chunks [1 ].id = GRAPH_CHUNKID_OIDLOOKUP ;
1648
1700
chunks [1 ].size = hashsz * ctx -> commits .nr ;
1701
+ chunks [1 ].write_fn = write_graph_chunk_oids ;
1649
1702
chunks [2 ].id = GRAPH_CHUNKID_DATA ;
1650
1703
chunks [2 ].size = (hashsz + 16 ) * ctx -> commits .nr ;
1704
+ chunks [2 ].write_fn = write_graph_chunk_data ;
1651
1705
if (ctx -> num_extra_edges ) {
1652
1706
chunks [num_chunks ].id = GRAPH_CHUNKID_EXTRAEDGES ;
1653
1707
chunks [num_chunks ].size = 4 * ctx -> num_extra_edges ;
1708
+ chunks [num_chunks ].write_fn = write_graph_chunk_extra_edges ;
1654
1709
num_chunks ++ ;
1655
1710
}
1656
1711
if (ctx -> changed_paths ) {
1657
1712
chunks [num_chunks ].id = GRAPH_CHUNKID_BLOOMINDEXES ;
1658
1713
chunks [num_chunks ].size = sizeof (uint32_t ) * ctx -> commits .nr ;
1714
+ chunks [num_chunks ].write_fn = write_graph_chunk_bloom_indexes ;
1659
1715
num_chunks ++ ;
1660
1716
chunks [num_chunks ].id = GRAPH_CHUNKID_BLOOMDATA ;
1661
1717
chunks [num_chunks ].size = sizeof (uint32_t ) * 3
1662
1718
+ ctx -> total_bloom_filter_data_size ;
1719
+ chunks [num_chunks ].write_fn = write_graph_chunk_bloom_data ;
1663
1720
num_chunks ++ ;
1664
1721
}
1665
1722
if (ctx -> num_commit_graphs_after > 1 ) {
1666
1723
chunks [num_chunks ].id = GRAPH_CHUNKID_BASE ;
1667
1724
chunks [num_chunks ].size = hashsz * (ctx -> num_commit_graphs_after - 1 );
1725
+ chunks [num_chunks ].write_fn = write_graph_chunk_base ;
1668
1726
num_chunks ++ ;
1669
1727
}
1670
1728
@@ -1700,19 +1758,19 @@ static int write_commit_graph_file(struct write_commit_graph_context *ctx)
1700
1758
progress_title .buf ,
1701
1759
num_chunks * ctx -> commits .nr );
1702
1760
}
1703
- write_graph_chunk_fanout (f , ctx );
1704
- write_graph_chunk_oids (f , hashsz , ctx );
1705
- write_graph_chunk_data (f , hashsz , ctx );
1706
- if (ctx -> num_extra_edges )
1707
- write_graph_chunk_extra_edges (f , ctx );
1708
- if (ctx -> changed_paths ) {
1709
- write_graph_chunk_bloom_indexes (f , ctx );
1710
- write_graph_chunk_bloom_data (f , ctx , & bloom_settings );
1711
- }
1712
- if (ctx -> num_commit_graphs_after > 1 &&
1713
- write_graph_chunk_base (f , ctx )) {
1714
- return -1 ;
1761
+
1762
+ for (i = 0 ; i < num_chunks ; i ++ ) {
1763
+ uint64_t start_offset = f -> total + f -> offset ;
1764
+
1765
+ if (chunks [i ].write_fn (f , ctx ))
1766
+ return -1 ;
1767
+
1768
+ if (f -> total + f -> offset != start_offset + chunks [i ].size )
1769
+ BUG ("expected to write %" PRId64 " bytes to chunk %" PRIx32 ", but wrote %" PRId64 " instead" ,
1770
+ chunks [i ].size , chunks [i ].id ,
1771
+ f -> total + f -> offset - start_offset );
1715
1772
}
1773
+
1716
1774
stop_progress (& ctx -> progress );
1717
1775
strbuf_release (& progress_title );
1718
1776
@@ -2046,9 +2104,23 @@ int write_commit_graph(struct object_directory *odb,
2046
2104
ctx -> report_progress = flags & COMMIT_GRAPH_WRITE_PROGRESS ? 1 : 0 ;
2047
2105
ctx -> split = flags & COMMIT_GRAPH_WRITE_SPLIT ? 1 : 0 ;
2048
2106
ctx -> split_opts = split_opts ;
2049
- ctx -> changed_paths = flags & COMMIT_GRAPH_WRITE_BLOOM_FILTERS ? 1 : 0 ;
2050
2107
ctx -> total_bloom_filter_data_size = 0 ;
2051
2108
2109
+ if (flags & COMMIT_GRAPH_WRITE_BLOOM_FILTERS )
2110
+ ctx -> changed_paths = 1 ;
2111
+ if (!(flags & COMMIT_GRAPH_NO_WRITE_BLOOM_FILTERS )) {
2112
+ struct commit_graph * g ;
2113
+ prepare_commit_graph_one (ctx -> r , ctx -> odb );
2114
+
2115
+ g = ctx -> r -> objects -> commit_graph ;
2116
+
2117
+ /* We have changed-paths already. Keep them in the next graph */
2118
+ if (g && g -> chunk_bloom_data ) {
2119
+ ctx -> changed_paths = 1 ;
2120
+ ctx -> bloom_settings = g -> bloom_filter_settings ;
2121
+ }
2122
+ }
2123
+
2052
2124
if (ctx -> split ) {
2053
2125
struct commit_graph * g ;
2054
2126
prepare_commit_graph (ctx -> r );
0 commit comments