593
return 0;
594
}
595
596
+enum odb_optimize_strategy {
597
+ ODB_OPTIMIZE_INCREMENTAL,
598
+ ODB_OPTIMIZE_GEOMETRIC,
599
+};
600
+
601
enum odb_optimize_flags {
602
/* Enable verbose logging and progress reporting. */
603
ODB_OPTIMIZE_VERBOSE = (1 << 0),
610
};
611
612
struct odb_optimize_options {
613
+ enum odb_optimize_strategy strategy;
614
enum odb_optimize_flags flags;
615
const char *prune_expire;
616
const char *expire_to;
864
*
865
* - Otherwise we perform an incremental repack.
866
*/
861
- if (!(opts->flags & ODB_OPTIMIZE_AUTO)) {
862
- struct string_list keep_pack = STRING_LIST_INIT_NODUP;
863
-
864
- if (opts->keep_largest_pack != -1) {
865
- if (opts->keep_largest_pack)
866
- find_base_packs(&keep_pack, 0);
867
- } else if (big_pack_threshold) {
868
- find_base_packs(&keep_pack, big_pack_threshold);
869
- }
870
-
871
- add_repack_all_option(opts, &keep_pack, &repack_cmd.args);
872
- string_list_clear(&keep_pack, 0);
873
- } else {
874
- if (too_many_packs(gc_auto_pack_limit)) {
867
+ switch (opts->strategy) {
868
+ case ODB_OPTIMIZE_INCREMENTAL:
869
+ if (!(opts->flags & ODB_OPTIMIZE_AUTO)) {
870
struct string_list keep_pack = STRING_LIST_INIT_NODUP;
871
877
- if (big_pack_threshold) {
878
- find_base_packs(&keep_pack, big_pack_threshold);
879
- if (keep_pack.nr >= gc_auto_pack_limit) {
880
- string_list_clear(&keep_pack, 0);
872
+ if (opts->keep_largest_pack != -1) {
873
+ if (opts->keep_largest_pack)
874
find_base_packs(&keep_pack, 0);
882
- }
883
- } else {
884
- struct packed_git *p = find_base_packs(&keep_pack, 0);
885
- uint64_t mem_have, mem_want;
886
-
887
- mem_have = total_ram();
888
- mem_want = estimate_repack_memory(p);
889
-
890
- /*
891
- * Only allow 1/2 of memory for pack-objects, leave
892
- * the rest for the OS and other processes in the
893
- * system.
894
- */
895
- if (!mem_have || mem_want < mem_have / 2)
896
- string_list_clear(&keep_pack, 0);
875
+ } else if (big_pack_threshold) {
876
+ find_base_packs(&keep_pack, big_pack_threshold);
877
}
878
879
add_repack_all_option(opts, &keep_pack, &repack_cmd.args);
880
string_list_clear(&keep_pack, 0);
881
} else {
902
- add_repack_incremental_option(&repack_cmd.args);
882
+ if (too_many_packs(gc_auto_pack_limit)) {
883
+ struct string_list keep_pack = STRING_LIST_INIT_NODUP;
884
+
885
+ if (big_pack_threshold) {
886
+ find_base_packs(&keep_pack, big_pack_threshold);
887
+ if (keep_pack.nr >= gc_auto_pack_limit) {
888
+ string_list_clear(&keep_pack, 0);
889
+ find_base_packs(&keep_pack, 0);
890
+ }
891
+ } else {
892
+ struct packed_git *p = find_base_packs(&keep_pack, 0);
893
+ uint64_t mem_have, mem_want;
894
+
895
+ mem_have = total_ram();
896
+ mem_want = estimate_repack_memory(p);
897
+
898
+ /*
899
+ * Only allow 1/2 of memory for pack-objects, leave
900
+ * the rest for the OS and other processes in the
901
+ * system.
902
+ */
903
+ if (!mem_have || mem_want < mem_have / 2)
904
+ string_list_clear(&keep_pack, 0);
905
+ }
906
+
907
+ add_repack_all_option(opts, &keep_pack, &repack_cmd.args);
908
+ string_list_clear(&keep_pack, 0);
909
+ } else {
910
+ add_repack_incremental_option(&repack_cmd.args);
911
+ }
912
}
913
+
914
+ break;
915
+ case ODB_OPTIMIZE_GEOMETRIC: {
916
+ struct pack_geometry geometry = {
917
+ .split_factor = 2,
918
+ };
919
+ struct pack_objects_args po_args = {
920
+ .local = 1,
921
+ };
922
+ struct existing_packs existing_packs = EXISTING_PACKS_INIT;
923
+ struct string_list kept_packs = STRING_LIST_INIT_DUP;
924
+
925
+ repo_config_get_int(the_repository, "maintenance.geometric-repack.splitFactor",
926
+ &geometry.split_factor);
927
+
928
+ existing_packs.repo = the_repository;
929
+ existing_packs_collect(&existing_packs, &kept_packs);
930
+ pack_geometry_init(&geometry, &existing_packs, &po_args);
931
+ pack_geometry_split(&geometry);
932
+
933
+ if (geometry.split < geometry.pack_nr) {
934
+ strvec_pushf(&repack_cmd.args, "--geometric=%d",
935
+ geometry.split_factor);
936
+ } else {
937
+ add_repack_all_option(opts, NULL, &repack_cmd.args);
938
+ }
939
+ if (the_repository->settings.core_multi_pack_index)
940
+ strvec_push(&repack_cmd.args, "--write-midx");
941
+
942
+ existing_packs_release(&existing_packs);
943
+ pack_geometry_release(&geometry);
944
+ break;
945
+ }
946
+ default:
947
+ die("unknown maintenance strategy '%d'", opts->strategy);
948
}
949
950
if (run_command(&repack_cmd)) {
952
goto out;
953
}
954
911
- if (opts->prune_expire) {
955
+ /* Geometric repacking uses cruft packs, so we don't have to prune separately. */
956
+ if (opts->strategy != ODB_OPTIMIZE_GEOMETRIC && opts->prune_expire) {
957
struct child_process prune_cmd = CHILD_PROCESS_INIT;
958
959
strvec_pushl(&prune_cmd.args, "prune", "--expire", NULL);
988
int aggressive)
989
{
990
struct odb_optimize_options odb_opts = {
991
+ .strategy = ODB_OPTIMIZE_INCREMENTAL,
992
.keep_largest_pack = keep_largest_pack,
993
OPTIMIZE_FIELDS_FROM_GC_CONFIG(cfg, aggressive),
994
};
1670
static int maintenance_task_geometric_repack(struct maintenance_run_opts *opts,
1671
struct gc_config *cfg)
1672
{
1627
- struct pack_geometry geometry = {
1628
- .split_factor = 2,
1629
- };
1630
- struct pack_objects_args po_args = {
1631
- .local = 1,
1673
+ struct odb_optimize_options odb_opts = {
1674
+ .strategy = ODB_OPTIMIZE_GEOMETRIC,
1675
+ OPTIMIZE_FIELDS_FROM_GC_CONFIG(cfg, 0),
1676
};
1633
- struct existing_packs existing_packs = EXISTING_PACKS_INIT;
1634
- struct string_list kept_packs = STRING_LIST_INIT_DUP;
1635
- struct child_process child = CHILD_PROCESS_INIT;
1636
- int ret;
1637
-
1638
- repo_config_get_int(the_repository, "maintenance.geometric-repack.splitFactor",
1639
- &geometry.split_factor);
1640
-
1641
- existing_packs.repo = the_repository;
1642
- existing_packs_collect(&existing_packs, &kept_packs);
1643
- pack_geometry_init(&geometry, &existing_packs, &po_args);
1644
- pack_geometry_split(&geometry);
1645
-
1646
- child.git_cmd = 1;
1647
- child.odb_to_close = the_repository->objects;
1648
-
1649
- strvec_pushl(&child.args, "repack", "-d", "-l", NULL);
1650
- if (geometry.split < geometry.pack_nr) {
1651
- strvec_pushf(&child.args, "--geometric=%d",
1652
- geometry.split_factor);
1653
- } else {
1654
- struct odb_optimize_options odb_opts = {
1655
- OPTIMIZE_FIELDS_FROM_GC_CONFIG(cfg, 0),
1656
- };
1677
1658
- if (!opts->quiet)
1659
- odb_opts.flags |= ODB_OPTIMIZE_VERBOSE;
1660
-
1661
- add_repack_all_option(&odb_opts, NULL, &child.args);
1662
- }
1663
- if (opts->quiet)
1664
- strvec_push(&child.args, "--quiet");
1665
- if (the_repository->settings.core_multi_pack_index)
1666
- strvec_push(&child.args, "--write-midx");
1667
-
1668
- if (run_command(&child)) {
1669
- ret = error(_("failed to perform geometric repack"));
1670
- goto out;
1671
- }
1672
-
1673
- ret = 0;
1678
+ if (!opts->quiet)
1679
+ odb_opts.flags |= ODB_OPTIMIZE_VERBOSE;
1680
1675
-out:
1676
- existing_packs_release(&existing_packs);
1677
- pack_geometry_release(&geometry);
1678
- return ret;
1681
+ return odb_optimize(the_repository->objects, &odb_opts);
1682
}
1683
1684
static int geometric_repack_auto_condition(struct gc_config *cfg UNUSED)