2 Copyright 2020 Google LLC
4 Use of this source code is governed by a BSD-style
5 license that can be found in the LICENSE file or at
6 https://developers.google.com/open-source/licenses/bsd
11 #include "../write-or-die.h"
16 #include "reftable-error.h"
17 #include "reftable-record.h"
18 #include "reftable-merged.h"
22 static int stack_try_add(struct reftable_stack
*st
,
23 int (*write_table
)(struct reftable_writer
*wr
,
26 static int stack_write_compact(struct reftable_stack
*st
,
27 struct reftable_writer
*wr
, int first
, int last
,
28 struct reftable_log_expiry_config
*config
);
29 static int stack_check_addition(struct reftable_stack
*st
,
30 const char *new_tab_name
);
31 static void reftable_addition_close(struct reftable_addition
*add
);
32 static int reftable_stack_reload_maybe_reuse(struct reftable_stack
*st
,
35 static void stack_filename(struct strbuf
*dest
, struct reftable_stack
*st
,
39 strbuf_addstr(dest
, st
->reftable_dir
);
40 strbuf_addstr(dest
, "/");
41 strbuf_addstr(dest
, name
);
44 static ssize_t
reftable_fd_write(void *arg
, const void *data
, size_t sz
)
46 int *fdp
= (int *)arg
;
47 return write_in_full(*fdp
, data
, sz
);
50 static int reftable_fd_flush(void *arg
)
52 int *fdp
= (int *)arg
;
54 return fsync_component(FSYNC_COMPONENT_REFERENCE
, *fdp
);
57 int reftable_new_stack(struct reftable_stack
**dest
, const char *dir
,
58 struct reftable_write_options config
)
60 struct reftable_stack
*p
=
61 reftable_calloc(sizeof(struct reftable_stack
));
62 struct strbuf list_file_name
= STRBUF_INIT
;
65 if (config
.hash_id
== 0) {
66 config
.hash_id
= GIT_SHA1_FORMAT_ID
;
71 strbuf_reset(&list_file_name
);
72 strbuf_addstr(&list_file_name
, dir
);
73 strbuf_addstr(&list_file_name
, "/tables.list");
75 p
->list_file
= strbuf_detach(&list_file_name
, NULL
);
77 p
->reftable_dir
= xstrdup(dir
);
80 err
= reftable_stack_reload_maybe_reuse(p
, 1);
82 reftable_stack_destroy(p
);
89 static int fd_read_lines(int fd
, char ***namesp
)
91 off_t size
= lseek(fd
, 0, SEEK_END
);
95 err
= REFTABLE_IO_ERROR
;
98 err
= lseek(fd
, 0, SEEK_SET
);
100 err
= REFTABLE_IO_ERROR
;
104 buf
= reftable_malloc(size
+ 1);
105 if (read_in_full(fd
, buf
, size
) != size
) {
106 err
= REFTABLE_IO_ERROR
;
111 parse_names(buf
, size
, namesp
);
118 int read_lines(const char *filename
, char ***namesp
)
120 int fd
= open(filename
, O_RDONLY
);
123 if (errno
== ENOENT
) {
124 *namesp
= reftable_calloc(sizeof(char *));
128 return REFTABLE_IO_ERROR
;
130 err
= fd_read_lines(fd
, namesp
);
135 struct reftable_merged_table
*
136 reftable_stack_merged_table(struct reftable_stack
*st
)
141 static int has_name(char **names
, const char *name
)
144 if (!strcmp(*names
, name
))
151 /* Close and free the stack */
152 void reftable_stack_destroy(struct reftable_stack
*st
)
157 reftable_merged_table_free(st
->merged
);
161 err
= read_lines(st
->list_file
, &names
);
163 FREE_AND_NULL(names
);
168 struct strbuf filename
= STRBUF_INIT
;
169 for (i
= 0; i
< st
->readers_len
; i
++) {
170 const char *name
= reader_name(st
->readers
[i
]);
171 strbuf_reset(&filename
);
172 if (names
&& !has_name(names
, name
)) {
173 stack_filename(&filename
, st
, name
);
175 reftable_reader_free(st
->readers
[i
]);
178 /* On Windows, can only unlink after closing. */
179 unlink(filename
.buf
);
182 strbuf_release(&filename
);
184 FREE_AND_NULL(st
->readers
);
187 if (st
->list_fd
>= 0) {
192 FREE_AND_NULL(st
->list_file
);
193 FREE_AND_NULL(st
->reftable_dir
);
198 static struct reftable_reader
**stack_copy_readers(struct reftable_stack
*st
,
201 struct reftable_reader
**cur
=
202 reftable_calloc(sizeof(struct reftable_reader
*) * cur_len
);
204 for (i
= 0; i
< cur_len
; i
++) {
205 cur
[i
] = st
->readers
[i
];
210 static int reftable_stack_reload_once(struct reftable_stack
*st
, char **names
,
213 int cur_len
= !st
->merged
? 0 : st
->merged
->stack_len
;
214 struct reftable_reader
**cur
= stack_copy_readers(st
, cur_len
);
216 int names_len
= names_length(names
);
217 struct reftable_reader
**new_readers
=
218 reftable_calloc(sizeof(struct reftable_reader
*) * names_len
);
219 struct reftable_table
*new_tables
=
220 reftable_calloc(sizeof(struct reftable_table
) * names_len
);
221 int new_readers_len
= 0;
222 struct reftable_merged_table
*new_merged
= NULL
;
223 struct strbuf table_path
= STRBUF_INIT
;
227 struct reftable_reader
*rd
= NULL
;
228 char *name
= *names
++;
230 /* this is linear; we assume compaction keeps the number of
231 tables under control so this is not quadratic. */
233 for (j
= 0; reuse_open
&& j
< cur_len
; j
++) {
234 if (cur
[j
] && 0 == strcmp(cur
[j
]->name
, name
)) {
242 struct reftable_block_source src
= { NULL
};
243 stack_filename(&table_path
, st
, name
);
245 err
= reftable_block_source_from_file(&src
,
250 err
= reftable_new_reader(&rd
, &src
, name
);
255 new_readers
[new_readers_len
] = rd
;
256 reftable_table_from_reader(&new_tables
[new_readers_len
], rd
);
261 err
= reftable_new_merged_table(&new_merged
, new_tables
,
262 new_readers_len
, st
->config
.hash_id
);
267 st
->readers_len
= new_readers_len
;
269 merged_table_release(st
->merged
);
270 reftable_merged_table_free(st
->merged
);
273 reftable_free(st
->readers
);
275 st
->readers
= new_readers
;
279 new_merged
->suppress_deletions
= 1;
280 st
->merged
= new_merged
;
281 for (i
= 0; i
< cur_len
; i
++) {
283 const char *name
= reader_name(cur
[i
]);
284 stack_filename(&table_path
, st
, name
);
286 reader_close(cur
[i
]);
287 reftable_reader_free(cur
[i
]);
289 /* On Windows, can only unlink after closing. */
290 unlink(table_path
.buf
);
295 for (i
= 0; i
< new_readers_len
; i
++) {
296 reader_close(new_readers
[i
]);
297 reftable_reader_free(new_readers
[i
]);
299 reftable_free(new_readers
);
300 reftable_free(new_tables
);
302 strbuf_release(&table_path
);
306 /* return negative if a before b. */
307 static int tv_cmp(struct timeval
*a
, struct timeval
*b
)
309 time_t diff
= a
->tv_sec
- b
->tv_sec
;
310 int udiff
= a
->tv_usec
- b
->tv_usec
;
318 static int reftable_stack_reload_maybe_reuse(struct reftable_stack
*st
,
321 char **names
= NULL
, **names_after
= NULL
;
322 struct timeval deadline
;
327 err
= gettimeofday(&deadline
, NULL
);
330 deadline
.tv_sec
+= 3;
335 err
= gettimeofday(&now
, NULL
);
340 * Only look at deadlines after the first few times. This
341 * simplifies debugging in GDB.
344 if (tries
> 3 && tv_cmp(&now
, &deadline
) >= 0)
347 fd
= open(st
->list_file
, O_RDONLY
);
349 if (errno
!= ENOENT
) {
350 err
= REFTABLE_IO_ERROR
;
354 names
= reftable_calloc(sizeof(char *));
356 err
= fd_read_lines(fd
, &names
);
361 err
= reftable_stack_reload_once(st
, names
, reuse_open
);
364 if (err
!= REFTABLE_NOT_EXIST_ERROR
)
368 * REFTABLE_NOT_EXIST_ERROR can be caused by a concurrent
369 * writer. Check if there was one by checking if the name list
372 err
= read_lines(st
->list_file
, &names_after
);
375 if (names_equal(names_after
, names
)) {
376 err
= REFTABLE_NOT_EXIST_ERROR
;
382 free_names(names_after
);
387 delay
= delay
+ (delay
* rand()) / RAND_MAX
+ 1;
388 sleep_millisec(delay
);
393 * Invalidate the stat cache. It is sufficient to only close the file
394 * descriptor and keep the cached stat info because we never use the
395 * latter when the former is negative.
397 if (st
->list_fd
>= 0) {
403 * Cache stat information in case it provides a useful signal to us.
404 * According to POSIX, "The st_ino and st_dev fields taken together
405 * uniquely identify the file within the system." That being said,
406 * Windows is not POSIX compliant and we do not have these fields
407 * available. So the information we have there is insufficient to
408 * determine whether two file descriptors point to the same file.
410 * While we could fall back to using other signals like the file's
411 * mtime, those are not sufficient to avoid races. We thus refrain from
412 * using the stat cache on such systems and fall back to the secondary
413 * caching mechanism, which is to check whether contents of the file
416 * On other systems which are POSIX compliant we must keep the file
417 * descriptor open. This is to avoid a race condition where two
418 * processes access the reftable stack at the same point in time:
420 * 1. A reads the reftable stack and caches its stat info.
422 * 2. B updates the stack, appending a new table to "tables.list".
423 * This will both use a new inode and result in a different file
424 * size, thus invalidating A's cache in theory.
426 * 3. B decides to auto-compact the stack and merges two tables. The
427 * file size now matches what A has cached again. Furthermore, the
428 * filesystem may decide to recycle the inode number of the file
429 * we have replaced in (2) because it is not in use anymore.
431 * 4. A reloads the reftable stack. Neither the inode number nor the
432 * file size changed. If the timestamps did not change either then
433 * we think the cached copy of our stack is up-to-date.
435 * By keeping the file descriptor open the inode number cannot be
436 * recycled, mitigating the race.
438 if (!err
&& fd
>= 0 && !fstat(fd
, &st
->list_st
) &&
439 st
->list_st
.st_dev
&& st
->list_st
.st_ino
) {
447 free_names(names_after
);
454 static int stack_uptodate(struct reftable_stack
*st
)
461 * When we have cached stat information available then we use it to
462 * verify whether the file has been rewritten.
464 * Note that we explicitly do not want to use `stat_validity_check()`
465 * and friends here because they may end up not comparing the `st_dev`
466 * and `st_ino` fields. These functions thus cannot guarantee that we
467 * indeed still have the same file.
469 if (st
->list_fd
>= 0) {
472 if (stat(st
->list_file
, &list_st
) < 0) {
474 * It's fine for "tables.list" to not exist. In that
475 * case, we have to refresh when the loaded stack has
479 return !!st
->readers_len
;
480 return REFTABLE_IO_ERROR
;
484 * When "tables.list" refers to the same file we can assume
485 * that it didn't change. This is because we always use
486 * rename(3P) to update the file and never write to it
489 if (st
->list_st
.st_dev
== list_st
.st_dev
&&
490 st
->list_st
.st_ino
== list_st
.st_ino
)
494 err
= read_lines(st
->list_file
, &names
);
498 for (i
= 0; i
< st
->readers_len
; i
++) {
504 if (strcmp(st
->readers
[i
]->name
, names
[i
])) {
510 if (names
[st
->merged
->stack_len
]) {
520 int reftable_stack_reload(struct reftable_stack
*st
)
522 int err
= stack_uptodate(st
);
524 return reftable_stack_reload_maybe_reuse(st
, 1);
528 int reftable_stack_add(struct reftable_stack
*st
,
529 int (*write
)(struct reftable_writer
*wr
, void *arg
),
532 int err
= stack_try_add(st
, write
, arg
);
534 if (err
== REFTABLE_LOCK_ERROR
) {
535 /* Ignore error return, we want to propagate
538 reftable_stack_reload(st
);
546 static void format_name(struct strbuf
*dest
, uint64_t min
, uint64_t max
)
549 uint32_t rnd
= (uint32_t)git_rand();
550 snprintf(buf
, sizeof(buf
), "0x%012" PRIx64
"-0x%012" PRIx64
"-%08x",
553 strbuf_addstr(dest
, buf
);
556 struct reftable_addition
{
557 struct tempfile
*lock_file
;
558 struct reftable_stack
*stack
;
562 uint64_t next_update_index
;
565 #define REFTABLE_ADDITION_INIT {0}
567 static int reftable_stack_init_addition(struct reftable_addition
*add
,
568 struct reftable_stack
*st
)
570 struct strbuf lock_file_name
= STRBUF_INIT
;
574 strbuf_addf(&lock_file_name
, "%s.lock", st
->list_file
);
576 add
->lock_file
= create_tempfile(lock_file_name
.buf
);
577 if (!add
->lock_file
) {
578 if (errno
== EEXIST
) {
579 err
= REFTABLE_LOCK_ERROR
;
581 err
= REFTABLE_IO_ERROR
;
585 if (st
->config
.default_permissions
) {
586 if (chmod(add
->lock_file
->filename
.buf
, st
->config
.default_permissions
) < 0) {
587 err
= REFTABLE_IO_ERROR
;
592 err
= stack_uptodate(st
);
597 err
= REFTABLE_LOCK_ERROR
;
601 add
->next_update_index
= reftable_stack_next_update_index(st
);
604 reftable_addition_close(add
);
606 strbuf_release(&lock_file_name
);
610 static void reftable_addition_close(struct reftable_addition
*add
)
613 struct strbuf nm
= STRBUF_INIT
;
614 for (i
= 0; i
< add
->new_tables_len
; i
++) {
615 stack_filename(&nm
, add
->stack
, add
->new_tables
[i
]);
617 reftable_free(add
->new_tables
[i
]);
618 add
->new_tables
[i
] = NULL
;
620 reftable_free(add
->new_tables
);
621 add
->new_tables
= NULL
;
622 add
->new_tables_len
= 0;
624 delete_tempfile(&add
->lock_file
);
628 void reftable_addition_destroy(struct reftable_addition
*add
)
633 reftable_addition_close(add
);
637 int reftable_addition_commit(struct reftable_addition
*add
)
639 struct strbuf table_list
= STRBUF_INIT
;
640 int lock_file_fd
= get_tempfile_fd(add
->lock_file
);
644 if (add
->new_tables_len
== 0)
647 for (i
= 0; i
< add
->stack
->merged
->stack_len
; i
++) {
648 strbuf_addstr(&table_list
, add
->stack
->readers
[i
]->name
);
649 strbuf_addstr(&table_list
, "\n");
651 for (i
= 0; i
< add
->new_tables_len
; i
++) {
652 strbuf_addstr(&table_list
, add
->new_tables
[i
]);
653 strbuf_addstr(&table_list
, "\n");
656 err
= write_in_full(lock_file_fd
, table_list
.buf
, table_list
.len
);
657 strbuf_release(&table_list
);
659 err
= REFTABLE_IO_ERROR
;
663 fsync_component_or_die(FSYNC_COMPONENT_REFERENCE
, lock_file_fd
,
664 get_tempfile_path(add
->lock_file
));
666 err
= rename_tempfile(&add
->lock_file
, add
->stack
->list_file
);
668 err
= REFTABLE_IO_ERROR
;
672 /* success, no more state to clean up. */
673 for (i
= 0; i
< add
->new_tables_len
; i
++) {
674 reftable_free(add
->new_tables
[i
]);
676 reftable_free(add
->new_tables
);
677 add
->new_tables
= NULL
;
678 add
->new_tables_len
= 0;
680 err
= reftable_stack_reload_maybe_reuse(add
->stack
, 1);
684 if (!add
->stack
->disable_auto_compact
)
685 err
= reftable_stack_auto_compact(add
->stack
);
688 reftable_addition_close(add
);
692 int reftable_stack_new_addition(struct reftable_addition
**dest
,
693 struct reftable_stack
*st
)
696 struct reftable_addition empty
= REFTABLE_ADDITION_INIT
;
697 *dest
= reftable_calloc(sizeof(**dest
));
699 err
= reftable_stack_init_addition(*dest
, st
);
701 reftable_free(*dest
);
707 static int stack_try_add(struct reftable_stack
*st
,
708 int (*write_table
)(struct reftable_writer
*wr
,
712 struct reftable_addition add
= REFTABLE_ADDITION_INIT
;
713 int err
= reftable_stack_init_addition(&add
, st
);
717 err
= REFTABLE_LOCK_ERROR
;
721 err
= reftable_addition_add(&add
, write_table
, arg
);
725 err
= reftable_addition_commit(&add
);
727 reftable_addition_close(&add
);
731 int reftable_addition_add(struct reftable_addition
*add
,
732 int (*write_table
)(struct reftable_writer
*wr
,
736 struct strbuf temp_tab_file_name
= STRBUF_INIT
;
737 struct strbuf tab_file_name
= STRBUF_INIT
;
738 struct strbuf next_name
= STRBUF_INIT
;
739 struct reftable_writer
*wr
= NULL
;
743 strbuf_reset(&next_name
);
744 format_name(&next_name
, add
->next_update_index
, add
->next_update_index
);
746 stack_filename(&temp_tab_file_name
, add
->stack
, next_name
.buf
);
747 strbuf_addstr(&temp_tab_file_name
, ".temp.XXXXXX");
749 tab_fd
= mkstemp(temp_tab_file_name
.buf
);
751 err
= REFTABLE_IO_ERROR
;
754 if (add
->stack
->config
.default_permissions
) {
755 if (chmod(temp_tab_file_name
.buf
, add
->stack
->config
.default_permissions
)) {
756 err
= REFTABLE_IO_ERROR
;
760 wr
= reftable_new_writer(reftable_fd_write
, reftable_fd_flush
, &tab_fd
,
761 &add
->stack
->config
);
762 err
= write_table(wr
, arg
);
766 err
= reftable_writer_close(wr
);
767 if (err
== REFTABLE_EMPTY_TABLE_ERROR
) {
777 err
= REFTABLE_IO_ERROR
;
781 err
= stack_check_addition(add
->stack
, temp_tab_file_name
.buf
);
785 if (wr
->min_update_index
< add
->next_update_index
) {
786 err
= REFTABLE_API_ERROR
;
790 format_name(&next_name
, wr
->min_update_index
, wr
->max_update_index
);
791 strbuf_addstr(&next_name
, ".ref");
793 stack_filename(&tab_file_name
, add
->stack
, next_name
.buf
);
796 On windows, this relies on rand() picking a unique destination name.
797 Maybe we should do retry loop as well?
799 err
= rename(temp_tab_file_name
.buf
, tab_file_name
.buf
);
801 err
= REFTABLE_IO_ERROR
;
805 add
->new_tables
= reftable_realloc(add
->new_tables
,
806 sizeof(*add
->new_tables
) *
807 (add
->new_tables_len
+ 1));
808 add
->new_tables
[add
->new_tables_len
] = strbuf_detach(&next_name
, NULL
);
809 add
->new_tables_len
++;
815 if (temp_tab_file_name
.len
> 0) {
816 unlink(temp_tab_file_name
.buf
);
819 strbuf_release(&temp_tab_file_name
);
820 strbuf_release(&tab_file_name
);
821 strbuf_release(&next_name
);
822 reftable_writer_free(wr
);
826 uint64_t reftable_stack_next_update_index(struct reftable_stack
*st
)
828 int sz
= st
->merged
->stack_len
;
830 return reftable_reader_max_update_index(st
->readers
[sz
- 1]) +
835 static int stack_compact_locked(struct reftable_stack
*st
, int first
, int last
,
836 struct strbuf
*temp_tab
,
837 struct reftable_log_expiry_config
*config
)
839 struct strbuf next_name
= STRBUF_INIT
;
841 struct reftable_writer
*wr
= NULL
;
844 format_name(&next_name
,
845 reftable_reader_min_update_index(st
->readers
[first
]),
846 reftable_reader_max_update_index(st
->readers
[last
]));
848 stack_filename(temp_tab
, st
, next_name
.buf
);
849 strbuf_addstr(temp_tab
, ".temp.XXXXXX");
851 tab_fd
= mkstemp(temp_tab
->buf
);
852 if (st
->config
.default_permissions
&&
853 chmod(temp_tab
->buf
, st
->config
.default_permissions
) < 0) {
854 err
= REFTABLE_IO_ERROR
;
858 wr
= reftable_new_writer(reftable_fd_write
, reftable_fd_flush
, &tab_fd
, &st
->config
);
860 err
= stack_write_compact(st
, wr
, first
, last
, config
);
863 err
= reftable_writer_close(wr
);
871 reftable_writer_free(wr
);
876 if (err
!= 0 && temp_tab
->len
> 0) {
877 unlink(temp_tab
->buf
);
878 strbuf_release(temp_tab
);
880 strbuf_release(&next_name
);
884 static int stack_write_compact(struct reftable_stack
*st
,
885 struct reftable_writer
*wr
, int first
, int last
,
886 struct reftable_log_expiry_config
*config
)
888 int subtabs_len
= last
- first
+ 1;
889 struct reftable_table
*subtabs
= reftable_calloc(
890 sizeof(struct reftable_table
) * (last
- first
+ 1));
891 struct reftable_merged_table
*mt
= NULL
;
893 struct reftable_iterator it
= { NULL
};
894 struct reftable_ref_record ref
= { NULL
};
895 struct reftable_log_record log
= { NULL
};
897 uint64_t entries
= 0;
900 for (i
= first
, j
= 0; i
<= last
; i
++) {
901 struct reftable_reader
*t
= st
->readers
[i
];
902 reftable_table_from_reader(&subtabs
[j
++], t
);
903 st
->stats
.bytes
+= t
->size
;
905 reftable_writer_set_limits(wr
, st
->readers
[first
]->min_update_index
,
906 st
->readers
[last
]->max_update_index
);
908 err
= reftable_new_merged_table(&mt
, subtabs
, subtabs_len
,
911 reftable_free(subtabs
);
915 err
= reftable_merged_table_seek_ref(mt
, &it
, "");
920 err
= reftable_iterator_next_ref(&it
, &ref
);
928 if (first
== 0 && reftable_ref_record_is_deletion(&ref
)) {
932 err
= reftable_writer_add_ref(wr
, &ref
);
937 reftable_iterator_destroy(&it
);
939 err
= reftable_merged_table_seek_log(mt
, &it
, "");
944 err
= reftable_iterator_next_log(&it
, &log
);
951 if (first
== 0 && reftable_log_record_is_deletion(&log
)) {
955 if (config
&& config
->min_update_index
> 0 &&
956 log
.update_index
< config
->min_update_index
) {
960 if (config
&& config
->time
> 0 &&
961 log
.value
.update
.time
< config
->time
) {
965 err
= reftable_writer_add_log(wr
, &log
);
972 reftable_iterator_destroy(&it
);
974 merged_table_release(mt
);
975 reftable_merged_table_free(mt
);
977 reftable_ref_record_release(&ref
);
978 reftable_log_record_release(&log
);
979 st
->stats
.entries_written
+= entries
;
983 /* < 0: error. 0 == OK, > 0 attempt failed; could retry. */
984 static int stack_compact_range(struct reftable_stack
*st
, int first
, int last
,
985 struct reftable_log_expiry_config
*expiry
)
987 struct strbuf temp_tab_file_name
= STRBUF_INIT
;
988 struct strbuf new_table_name
= STRBUF_INIT
;
989 struct strbuf lock_file_name
= STRBUF_INIT
;
990 struct strbuf ref_list_contents
= STRBUF_INIT
;
991 struct strbuf new_table_path
= STRBUF_INIT
;
994 int lock_file_fd
= -1;
995 int compact_count
= last
- first
+ 1;
997 char **delete_on_success
=
998 reftable_calloc(sizeof(char *) * (compact_count
+ 1));
999 char **subtable_locks
=
1000 reftable_calloc(sizeof(char *) * (compact_count
+ 1));
1003 int is_empty_table
= 0;
1005 if (first
> last
|| (!expiry
&& first
== last
)) {
1010 st
->stats
.attempts
++;
1012 strbuf_reset(&lock_file_name
);
1013 strbuf_addstr(&lock_file_name
, st
->list_file
);
1014 strbuf_addstr(&lock_file_name
, ".lock");
1017 open(lock_file_name
.buf
, O_EXCL
| O_CREAT
| O_WRONLY
, 0666);
1018 if (lock_file_fd
< 0) {
1019 if (errno
== EEXIST
) {
1022 err
= REFTABLE_IO_ERROR
;
1026 /* Don't want to write to the lock for now. */
1027 close(lock_file_fd
);
1031 err
= stack_uptodate(st
);
1035 for (i
= first
, j
= 0; i
<= last
; i
++) {
1036 struct strbuf subtab_file_name
= STRBUF_INIT
;
1037 struct strbuf subtab_lock
= STRBUF_INIT
;
1038 int sublock_file_fd
= -1;
1040 stack_filename(&subtab_file_name
, st
,
1041 reader_name(st
->readers
[i
]));
1043 strbuf_reset(&subtab_lock
);
1044 strbuf_addbuf(&subtab_lock
, &subtab_file_name
);
1045 strbuf_addstr(&subtab_lock
, ".lock");
1047 sublock_file_fd
= open(subtab_lock
.buf
,
1048 O_EXCL
| O_CREAT
| O_WRONLY
, 0666);
1049 if (sublock_file_fd
>= 0) {
1050 close(sublock_file_fd
);
1051 } else if (sublock_file_fd
< 0) {
1052 if (errno
== EEXIST
) {
1055 err
= REFTABLE_IO_ERROR
;
1059 subtable_locks
[j
] = subtab_lock
.buf
;
1060 delete_on_success
[j
] = subtab_file_name
.buf
;
1067 err
= unlink(lock_file_name
.buf
);
1072 err
= stack_compact_locked(st
, first
, last
, &temp_tab_file_name
,
1074 /* Compaction + tombstones can create an empty table out of non-empty
1076 is_empty_table
= (err
== REFTABLE_EMPTY_TABLE_ERROR
);
1077 if (is_empty_table
) {
1084 open(lock_file_name
.buf
, O_EXCL
| O_CREAT
| O_WRONLY
, 0666);
1085 if (lock_file_fd
< 0) {
1086 if (errno
== EEXIST
) {
1089 err
= REFTABLE_IO_ERROR
;
1094 if (st
->config
.default_permissions
) {
1095 if (chmod(lock_file_name
.buf
, st
->config
.default_permissions
) < 0) {
1096 err
= REFTABLE_IO_ERROR
;
1101 format_name(&new_table_name
, st
->readers
[first
]->min_update_index
,
1102 st
->readers
[last
]->max_update_index
);
1103 strbuf_addstr(&new_table_name
, ".ref");
1105 stack_filename(&new_table_path
, st
, new_table_name
.buf
);
1107 if (!is_empty_table
) {
1109 err
= rename(temp_tab_file_name
.buf
, new_table_path
.buf
);
1111 err
= REFTABLE_IO_ERROR
;
1116 for (i
= 0; i
< first
; i
++) {
1117 strbuf_addstr(&ref_list_contents
, st
->readers
[i
]->name
);
1118 strbuf_addstr(&ref_list_contents
, "\n");
1120 if (!is_empty_table
) {
1121 strbuf_addbuf(&ref_list_contents
, &new_table_name
);
1122 strbuf_addstr(&ref_list_contents
, "\n");
1124 for (i
= last
+ 1; i
< st
->merged
->stack_len
; i
++) {
1125 strbuf_addstr(&ref_list_contents
, st
->readers
[i
]->name
);
1126 strbuf_addstr(&ref_list_contents
, "\n");
1129 err
= write_in_full(lock_file_fd
, ref_list_contents
.buf
, ref_list_contents
.len
);
1131 err
= REFTABLE_IO_ERROR
;
1132 unlink(new_table_path
.buf
);
1136 err
= fsync_component(FSYNC_COMPONENT_REFERENCE
, lock_file_fd
);
1138 err
= REFTABLE_IO_ERROR
;
1139 unlink(new_table_path
.buf
);
1143 err
= close(lock_file_fd
);
1146 err
= REFTABLE_IO_ERROR
;
1147 unlink(new_table_path
.buf
);
1151 err
= rename(lock_file_name
.buf
, st
->list_file
);
1153 err
= REFTABLE_IO_ERROR
;
1154 unlink(new_table_path
.buf
);
1159 /* Reload the stack before deleting. On windows, we can only delete the
1160 files after we closed them.
1162 err
= reftable_stack_reload_maybe_reuse(st
, first
< last
);
1164 listp
= delete_on_success
;
1166 if (strcmp(*listp
, new_table_path
.buf
)) {
1173 free_names(delete_on_success
);
1175 listp
= subtable_locks
;
1180 free_names(subtable_locks
);
1181 if (lock_file_fd
>= 0) {
1182 close(lock_file_fd
);
1186 unlink(lock_file_name
.buf
);
1188 strbuf_release(&new_table_name
);
1189 strbuf_release(&new_table_path
);
1190 strbuf_release(&ref_list_contents
);
1191 strbuf_release(&temp_tab_file_name
);
1192 strbuf_release(&lock_file_name
);
1196 int reftable_stack_compact_all(struct reftable_stack
*st
,
1197 struct reftable_log_expiry_config
*config
)
1199 return stack_compact_range(st
, 0, st
->merged
->stack_len
- 1, config
);
1202 static int stack_compact_range_stats(struct reftable_stack
*st
, int first
,
1204 struct reftable_log_expiry_config
*config
)
1206 int err
= stack_compact_range(st
, first
, last
, config
);
1208 st
->stats
.failures
++;
1213 static int segment_size(struct segment
*s
)
1215 return s
->end
- s
->start
;
1218 int fastlog2(uint64_t sz
)
1223 for (; sz
; sz
/= 2) {
1229 struct segment
*sizes_to_segments(int *seglen
, uint64_t *sizes
, int n
)
1231 struct segment
*segs
= reftable_calloc(sizeof(struct segment
) * n
);
1233 struct segment cur
= { 0 };
1240 for (i
= 0; i
< n
; i
++) {
1241 int log
= fastlog2(sizes
[i
]);
1242 if (cur
.log
!= log
&& cur
.bytes
> 0) {
1243 struct segment fresh
= {
1253 cur
.bytes
+= sizes
[i
];
1260 struct segment
suggest_compaction_segment(uint64_t *sizes
, int n
)
1263 struct segment
*segs
= sizes_to_segments(&seglen
, sizes
, n
);
1264 struct segment min_seg
= {
1268 for (i
= 0; i
< seglen
; i
++) {
1269 if (segment_size(&segs
[i
]) == 1) {
1273 if (segs
[i
].log
< min_seg
.log
) {
1278 while (min_seg
.start
> 0) {
1279 int prev
= min_seg
.start
- 1;
1280 if (fastlog2(min_seg
.bytes
) < fastlog2(sizes
[prev
])) {
1284 min_seg
.start
= prev
;
1285 min_seg
.bytes
+= sizes
[prev
];
1288 reftable_free(segs
);
1292 static uint64_t *stack_table_sizes_for_compaction(struct reftable_stack
*st
)
1295 reftable_calloc(sizeof(uint64_t) * st
->merged
->stack_len
);
1296 int version
= (st
->config
.hash_id
== GIT_SHA1_FORMAT_ID
) ? 1 : 2;
1297 int overhead
= header_size(version
) - 1;
1299 for (i
= 0; i
< st
->merged
->stack_len
; i
++) {
1300 sizes
[i
] = st
->readers
[i
]->size
- overhead
;
1305 int reftable_stack_auto_compact(struct reftable_stack
*st
)
1307 uint64_t *sizes
= stack_table_sizes_for_compaction(st
);
1308 struct segment seg
=
1309 suggest_compaction_segment(sizes
, st
->merged
->stack_len
);
1310 reftable_free(sizes
);
1311 if (segment_size(&seg
) > 0)
1312 return stack_compact_range_stats(st
, seg
.start
, seg
.end
- 1,
1318 struct reftable_compaction_stats
*
1319 reftable_stack_compaction_stats(struct reftable_stack
*st
)
1324 int reftable_stack_read_ref(struct reftable_stack
*st
, const char *refname
,
1325 struct reftable_ref_record
*ref
)
1327 struct reftable_table tab
= { NULL
};
1328 reftable_table_from_merged_table(&tab
, reftable_stack_merged_table(st
));
1329 return reftable_table_read_ref(&tab
, refname
, ref
);
1332 int reftable_stack_read_log(struct reftable_stack
*st
, const char *refname
,
1333 struct reftable_log_record
*log
)
1335 struct reftable_iterator it
= { NULL
};
1336 struct reftable_merged_table
*mt
= reftable_stack_merged_table(st
);
1337 int err
= reftable_merged_table_seek_log(mt
, &it
, refname
);
1341 err
= reftable_iterator_next_log(&it
, log
);
1345 if (strcmp(log
->refname
, refname
) ||
1346 reftable_log_record_is_deletion(log
)) {
1353 reftable_log_record_release(log
);
1355 reftable_iterator_destroy(&it
);
1359 static int stack_check_addition(struct reftable_stack
*st
,
1360 const char *new_tab_name
)
1363 struct reftable_block_source src
= { NULL
};
1364 struct reftable_reader
*rd
= NULL
;
1365 struct reftable_table tab
= { NULL
};
1366 struct reftable_ref_record
*refs
= NULL
;
1367 struct reftable_iterator it
= { NULL
};
1372 if (st
->config
.skip_name_check
)
1375 err
= reftable_block_source_from_file(&src
, new_tab_name
);
1379 err
= reftable_new_reader(&rd
, &src
, new_tab_name
);
1383 err
= reftable_reader_seek_ref(rd
, &it
, "");
1392 struct reftable_ref_record ref
= { NULL
};
1393 err
= reftable_iterator_next_ref(&it
, &ref
);
1402 refs
= reftable_realloc(refs
, cap
* sizeof(refs
[0]));
1408 reftable_table_from_merged_table(&tab
, reftable_stack_merged_table(st
));
1410 err
= validate_ref_record_addition(tab
, refs
, len
);
1413 for (i
= 0; i
< len
; i
++) {
1414 reftable_ref_record_release(&refs
[i
]);
1418 reftable_iterator_destroy(&it
);
1419 reftable_reader_free(rd
);
1423 static int is_table_name(const char *s
)
1425 const char *dot
= strrchr(s
, '.');
1426 return dot
&& !strcmp(dot
, ".ref");
1429 static void remove_maybe_stale_table(struct reftable_stack
*st
, uint64_t max
,
1433 uint64_t update_idx
= 0;
1434 struct reftable_block_source src
= { NULL
};
1435 struct reftable_reader
*rd
= NULL
;
1436 struct strbuf table_path
= STRBUF_INIT
;
1437 stack_filename(&table_path
, st
, name
);
1439 err
= reftable_block_source_from_file(&src
, table_path
.buf
);
1443 err
= reftable_new_reader(&rd
, &src
, name
);
1447 update_idx
= reftable_reader_max_update_index(rd
);
1448 reftable_reader_free(rd
);
1450 if (update_idx
<= max
) {
1451 unlink(table_path
.buf
);
1454 strbuf_release(&table_path
);
1457 static int reftable_stack_clean_locked(struct reftable_stack
*st
)
1459 uint64_t max
= reftable_merged_table_max_update_index(
1460 reftable_stack_merged_table(st
));
1461 DIR *dir
= opendir(st
->reftable_dir
);
1462 struct dirent
*d
= NULL
;
1464 return REFTABLE_IO_ERROR
;
1467 while ((d
= readdir(dir
))) {
1470 if (!is_table_name(d
->d_name
))
1473 for (i
= 0; !found
&& i
< st
->readers_len
; i
++) {
1474 found
= !strcmp(reader_name(st
->readers
[i
]), d
->d_name
);
1479 remove_maybe_stale_table(st
, max
, d
->d_name
);
1486 int reftable_stack_clean(struct reftable_stack
*st
)
1488 struct reftable_addition
*add
= NULL
;
1489 int err
= reftable_stack_new_addition(&add
, st
);
1494 err
= reftable_stack_reload(st
);
1499 err
= reftable_stack_clean_locked(st
);
1502 reftable_addition_destroy(add
);
1506 int reftable_stack_print_directory(const char *stackdir
, uint32_t hash_id
)
1508 struct reftable_stack
*stack
= NULL
;
1509 struct reftable_write_options cfg
= { .hash_id
= hash_id
};
1510 struct reftable_merged_table
*merged
= NULL
;
1511 struct reftable_table table
= { NULL
};
1513 int err
= reftable_new_stack(&stack
, stackdir
, cfg
);
1517 merged
= reftable_stack_merged_table(stack
);
1518 reftable_table_from_merged_table(&table
, merged
);
1519 err
= reftable_table_print(&table
);
1522 reftable_stack_destroy(stack
);