The struct `reftable_addition` is used to modify a given stack, as such, it also includes a `struct reftable_flock` used to obtain the lock to the list file. While the scope of the field lies within this struct, it doesn't allow for optimizations to be made on `struct reftable_stack` itself. Move the field to `struct reftable_stack`, allowing us to make a simple optimization around avoiding a stack reload when we have already obtained a lock. While this is currently possible in the write path, the write path also contains multiple branches to reads which only work on top of `struct reftable_stack`, and we would miss the optimization in such paths. Since the lock is now shared across all additions on the same stack, a second `reftable_addition` that fails to acquire the already held lock would still call `reftable_addition_close()`, which will release the `stack->list_lock` which is still held by the first addition. To avoid this, add a new bit field `locked` to `reftable_addition` that tracks whether a particular addition is the one holding the lock, and only release it in that case. Add a unit test to validate this behavior. While here, remove an unused header file from 'reftable/stack.h'. Signed-off-by: Karthik Nayak <karthik.188@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
47 lines
937 B
C
47 lines
937 B
C
/*
|
|
* Copyright 2020 Google LLC
|
|
*
|
|
* Use of this source code is governed by a BSD-style
|
|
* license that can be found in the LICENSE file or at
|
|
* https://developers.google.com/open-source/licenses/bsd
|
|
*/
|
|
|
|
#ifndef STACK_H
|
|
#define STACK_H
|
|
|
|
#include "system.h"
|
|
#include "reftable-stack.h"
|
|
|
|
struct reftable_stack {
|
|
struct stat list_st;
|
|
char *list_file;
|
|
int list_fd;
|
|
|
|
/*
|
|
* Set while an addition holds the stack locked. Used by
|
|
* stack_uptodate() to skip reload checks while locked.
|
|
*/
|
|
struct reftable_flock list_lock;
|
|
|
|
char *reftable_dir;
|
|
|
|
struct reftable_stack_options opts;
|
|
|
|
struct reftable_table **tables;
|
|
size_t tables_len;
|
|
struct reftable_merged_table *merged;
|
|
struct reftable_compaction_stats stats;
|
|
};
|
|
|
|
int read_lines(const char *filename, char ***lines);
|
|
|
|
struct segment {
|
|
size_t start, end;
|
|
uint64_t bytes;
|
|
};
|
|
|
|
struct segment suggest_compaction_segment(uint64_t *sizes, size_t n,
|
|
uint8_t factor);
|
|
|
|
#endif
|