TDBStore: the work buffer is at least the program size or 64 bytes

Previously, we always set the work buffer to 64 bytes, without
checking it was no less the actual program size. But we can't
simply switch to use the program size for the work buffer,
because if it's too small (e.g. 1 byte in some cases), we
will not be able to read the status header (24 bytes), and
small buffers means more underlying write operations and
lower efficiency.

This PR changes the work buffer size to be the program size,
or 64 bytes as an absolute minimum like before.
pull/13996/head
Lingkai Dong 2020-12-02 14:36:30 +00:00
parent ece756c0c4
commit cf977b7aae
2 changed files with 9 additions and 7 deletions

View File

@ -308,6 +308,7 @@ private:
tdbstore_area_data_t _area_params[_num_areas];
uint32_t _prog_size;
uint8_t *_work_buf;
size_t _work_buf_size;
char *_key_buf;
void *_inc_set_handle;
void *_iterator_table[_max_open_iterators];

View File

@ -77,7 +77,7 @@ typedef struct {
uint32_t crc;
} reserved_trailer_t;
static const uint32_t work_buf_size = 64;
static const size_t min_work_buf_size = 64;
static const uint32_t initial_crc = 0xFFFFFFFF;
static const uint32_t initial_max_keys = 16;
@ -130,7 +130,7 @@ static uint32_t calc_crc(uint32_t init_crc, uint32_t data_size, const void *data
TDBStore::TDBStore(BlockDevice *bd) : _ram_table(0), _max_keys(0),
_num_keys(0), _bd(bd), _buff_bd(0), _free_space_offset(0), _master_record_offset(0),
_master_record_size(0), _is_initialized(false), _active_area(0), _active_area_version(0), _size(0),
_area_params{}, _prog_size(0), _work_buf(0), _key_buf(0), _inc_set_handle(0)
_area_params{}, _prog_size(0), _work_buf(0), _work_buf_size(0), _key_buf(0), _inc_set_handle(0)
{
for (int i = 0; i < _num_areas; i++) {
_area_params[i] = { 0 };
@ -327,7 +327,7 @@ int TDBStore::read_record(uint8_t area, uint32_t offset, char *key,
user_key_ptr[key_size] = '\0';
} else {
dest_buf = _work_buf;
chunk_size = std::min(key_size, work_buf_size);
chunk_size = std::min(key_size, _work_buf_size);
}
} else {
// This means that we're on the data part
@ -337,13 +337,13 @@ int TDBStore::read_record(uint8_t area, uint32_t offset, char *key,
// 3. After actual part is finished - read to work buffer
// 4. Copy data flag not set - read to work buffer
if (curr_data_offset < data_offset) {
chunk_size = std::min((size_t)work_buf_size, (size_t)(data_offset - curr_data_offset));
chunk_size = std::min<size_t>(_work_buf_size, (data_offset - curr_data_offset));
dest_buf = _work_buf;
} else if (copy_data && (curr_data_offset < data_offset + actual_data_size)) {
chunk_size = actual_data_size;
dest_buf = static_cast<uint8_t *>(data_buf);
} else {
chunk_size = std::min(work_buf_size, total_size);
chunk_size = std::min<size_t>(_work_buf_size, total_size);
dest_buf = _work_buf;
}
}
@ -860,7 +860,7 @@ int TDBStore::copy_record(uint8_t from_area, uint32_t from_offset, uint32_t to_o
total_size -= chunk_size;
while (total_size) {
chunk_size = std::min(total_size, work_buf_size);
chunk_size = std::min(total_size, _work_buf_size);
ret = read_area(from_area, from_offset, chunk_size, _work_buf);
if (ret) {
return ret;
@ -1044,7 +1044,8 @@ int TDBStore::init()
}
_prog_size = _bd->get_program_size();
_work_buf = new uint8_t[work_buf_size];
_work_buf_size = std::max<size_t>(_prog_size, min_work_buf_size);
_work_buf = new uint8_t[_work_buf_size];
_key_buf = new char[MAX_KEY_SIZE];
_inc_set_handle = new inc_set_handle_t;
memset(_inc_set_handle, 0, sizeof(inc_set_handle_t));