reftable: make the compaction factor configurable
When auto-compacting, the reftable library packs references such that the sizes of the tables form a geometric sequence. The factor for this geometric sequence is hardcoded to 2 right now. We're about to expose this as a config option though, so let's expose the factor via write options. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
		 Patrick Steinhardt
					Patrick Steinhardt
				
			
				
					committed by
					
						 Junio C Hamano
						Junio C Hamano
					
				
			
			
				
	
			
			
			 Junio C Hamano
						Junio C Hamano
					
				
			
						parent
						
							afbdbfae0b
						
					
				
				
					commit
					f663d34306
				
			| @ -17,5 +17,6 @@ https://developers.google.com/open-source/licenses/bsd | |||||||
|  |  | ||||||
| #define MAX_RESTARTS ((1 << 16) - 1) | #define MAX_RESTARTS ((1 << 16) - 1) | ||||||
| #define DEFAULT_BLOCK_SIZE 4096 | #define DEFAULT_BLOCK_SIZE 4096 | ||||||
|  | #define DEFAULT_GEOMETRIC_FACTOR 2 | ||||||
|  |  | ||||||
| #endif | #endif | ||||||
|  | |||||||
| @ -45,6 +45,12 @@ struct reftable_write_options { | |||||||
|  |  | ||||||
| 	/* boolean: Prevent auto-compaction of tables. */ | 	/* boolean: Prevent auto-compaction of tables. */ | ||||||
| 	unsigned disable_auto_compact : 1; | 	unsigned disable_auto_compact : 1; | ||||||
|  |  | ||||||
|  | 	/* | ||||||
|  | 	 * Geometric sequence factor used by auto-compaction to decide which | ||||||
|  | 	 * tables to compact. Defaults to 2 if unset. | ||||||
|  | 	 */ | ||||||
|  | 	uint8_t auto_compaction_factor; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| /* reftable_block_stats holds statistics for a single block type */ | /* reftable_block_stats holds statistics for a single block type */ | ||||||
|  | |||||||
| @ -10,6 +10,7 @@ https://developers.google.com/open-source/licenses/bsd | |||||||
|  |  | ||||||
| #include "../write-or-die.h" | #include "../write-or-die.h" | ||||||
| #include "system.h" | #include "system.h" | ||||||
|  | #include "constants.h" | ||||||
| #include "merged.h" | #include "merged.h" | ||||||
| #include "reader.h" | #include "reader.h" | ||||||
| #include "reftable-error.h" | #include "reftable-error.h" | ||||||
| @ -1212,12 +1213,16 @@ static int segment_size(struct segment *s) | |||||||
| 	return s->end - s->start; | 	return s->end - s->start; | ||||||
| } | } | ||||||
|  |  | ||||||
| struct segment suggest_compaction_segment(uint64_t *sizes, size_t n) | struct segment suggest_compaction_segment(uint64_t *sizes, size_t n, | ||||||
|  | 					  uint8_t factor) | ||||||
| { | { | ||||||
| 	struct segment seg = { 0 }; | 	struct segment seg = { 0 }; | ||||||
| 	uint64_t bytes; | 	uint64_t bytes; | ||||||
| 	size_t i; | 	size_t i; | ||||||
|  |  | ||||||
|  | 	if (!factor) | ||||||
|  | 		factor = DEFAULT_GEOMETRIC_FACTOR; | ||||||
|  |  | ||||||
| 	/* | 	/* | ||||||
| 	 * If there are no tables or only a single one then we don't have to | 	 * If there are no tables or only a single one then we don't have to | ||||||
| 	 * compact anything. The sequence is geometric by definition already. | 	 * compact anything. The sequence is geometric by definition already. | ||||||
| @ -1249,7 +1254,7 @@ struct segment suggest_compaction_segment(uint64_t *sizes, size_t n) | |||||||
| 	 * 	64, 32, 16, 8, 4, 3, 1 | 	 * 	64, 32, 16, 8, 4, 3, 1 | ||||||
| 	 */ | 	 */ | ||||||
| 	for (i = n - 1; i > 0; i--) { | 	for (i = n - 1; i > 0; i--) { | ||||||
| 		if (sizes[i - 1] < sizes[i] * 2) { | 		if (sizes[i - 1] < sizes[i] * factor) { | ||||||
| 			seg.end = i + 1; | 			seg.end = i + 1; | ||||||
| 			bytes = sizes[i]; | 			bytes = sizes[i]; | ||||||
| 			break; | 			break; | ||||||
| @ -1275,7 +1280,7 @@ struct segment suggest_compaction_segment(uint64_t *sizes, size_t n) | |||||||
| 		uint64_t curr = bytes; | 		uint64_t curr = bytes; | ||||||
| 		bytes += sizes[i - 1]; | 		bytes += sizes[i - 1]; | ||||||
|  |  | ||||||
| 		if (sizes[i - 1] < curr * 2) { | 		if (sizes[i - 1] < curr * factor) { | ||||||
| 			seg.start = i - 1; | 			seg.start = i - 1; | ||||||
| 			seg.bytes = bytes; | 			seg.bytes = bytes; | ||||||
| 		} | 		} | ||||||
| @ -1301,7 +1306,8 @@ int reftable_stack_auto_compact(struct reftable_stack *st) | |||||||
| { | { | ||||||
| 	uint64_t *sizes = stack_table_sizes_for_compaction(st); | 	uint64_t *sizes = stack_table_sizes_for_compaction(st); | ||||||
| 	struct segment seg = | 	struct segment seg = | ||||||
| 		suggest_compaction_segment(sizes, st->merged->stack_len); | 		suggest_compaction_segment(sizes, st->merged->stack_len, | ||||||
|  | 					   st->opts.auto_compaction_factor); | ||||||
| 	reftable_free(sizes); | 	reftable_free(sizes); | ||||||
| 	if (segment_size(&seg) > 0) | 	if (segment_size(&seg) > 0) | ||||||
| 		return stack_compact_range_stats(st, seg.start, seg.end - 1, | 		return stack_compact_range_stats(st, seg.start, seg.end - 1, | ||||||
|  | |||||||
| @ -35,6 +35,7 @@ struct segment { | |||||||
| 	uint64_t bytes; | 	uint64_t bytes; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| struct segment suggest_compaction_segment(uint64_t *sizes, size_t n); | struct segment suggest_compaction_segment(uint64_t *sizes, size_t n, | ||||||
|  | 					  uint8_t factor); | ||||||
|  |  | ||||||
| #endif | #endif | ||||||
|  | |||||||
| @ -729,7 +729,7 @@ static void test_suggest_compaction_segment(void) | |||||||
| { | { | ||||||
| 	uint64_t sizes[] = { 512, 64, 17, 16, 9, 9, 9, 16, 2, 16 }; | 	uint64_t sizes[] = { 512, 64, 17, 16, 9, 9, 9, 16, 2, 16 }; | ||||||
| 	struct segment min = | 	struct segment min = | ||||||
| 		suggest_compaction_segment(sizes, ARRAY_SIZE(sizes)); | 		suggest_compaction_segment(sizes, ARRAY_SIZE(sizes), 2); | ||||||
| 	EXPECT(min.start == 1); | 	EXPECT(min.start == 1); | ||||||
| 	EXPECT(min.end == 10); | 	EXPECT(min.end == 10); | ||||||
| } | } | ||||||
| @ -738,7 +738,7 @@ static void test_suggest_compaction_segment_nothing(void) | |||||||
| { | { | ||||||
| 	uint64_t sizes[] = { 64, 32, 16, 8, 4, 2 }; | 	uint64_t sizes[] = { 64, 32, 16, 8, 4, 2 }; | ||||||
| 	struct segment result = | 	struct segment result = | ||||||
| 		suggest_compaction_segment(sizes, ARRAY_SIZE(sizes)); | 		suggest_compaction_segment(sizes, ARRAY_SIZE(sizes), 2); | ||||||
| 	EXPECT(result.start == result.end); | 	EXPECT(result.start == result.end); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user