Skip to content

Commit

Permalink
Write the freespace entries in a way that more carefully aligns with …
Browse files Browse the repository at this point in the history
…how they were reserved
  • Loading branch information
kriszyp committed Mar 13, 2024
1 parent 5799c8c commit 233bbc6
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 20 deletions.
47 changes: 28 additions & 19 deletions dependencies/lmdb/libraries/liblmdb/mdb.c
Original file line number Diff line number Diff line change
Expand Up @@ -4321,49 +4321,58 @@ mdb_freelist_save(MDB_txn *txn)
for (txnid_t id = start_written; id <= pglast; id++) {
key.mv_size = sizeof(id);
key.mv_data = &id;
mdb_cursor_get(&mc, &key, &data, MDB_SET_KEY);
rc = mdb_cursor_get(&mc, &key, &data, MDB_SET_KEY);
if (rc == MDB_NOTFOUND) {
mdb_tassert(txn, mop_len == 0);
rc = 0; // this is acceptable as long as there are no entries to write
break;
}


// fprintf(stderr, "put %u: ", id);

int len = (data.mv_size / sizeof(id)) - 1;
int reserved_len = (data.mv_size / sizeof(id)) - 1;
ssize_t reserved_end = reserved_space;
ssize_t end = mop_len;
ssize_t save_end = mop[end];
if (save_end < 0) {
// ends with a block length, zero it out, was already handled by previous iteration
mop[end] = 0;
}
ssize_t start = mop_len - len;
if (start < 0) {
// oversized entry, just use the remaining length
len = mop_len;
start = 0;
}
ssize_t start = reserved_space - reserved_len;
int len = end - start;
if (len < 0) len = 0;

ssize_t save2 = 0;
ssize_t save = mop[start];
if (len > entry_size) {
if (reserved_len > entry_size) {
// full blocks
// we have an extra overlapping byte to handle block length prefix. But don't use it if it is a page number
// because it could be preceded by a block length prefix, instead zero it out
save2 = mop[start + 1];
if (save2 > 0) {
mop[start + 1] = 0;
}
mop_len -= entry_size;
reserved_space = start + 1;

} else {
if (mop_len > entry_size) {
fprintf(stderr, "mop_len to large %u %u %u %u %u %u", reserved_space, mop_len, entry_size, start_written, id, pglast);
if (reserved_space > entry_size) {
fprintf(stderr, "reserved_space to large %u %u %u %u %u %u", reserved_space, mop_len, entry_size, start_written, id, pglast);
}
mdb_tassert(txn, mop_len <= entry_size);
mop_len = 0; // nothing left to save
mdb_tassert(txn, reserved_space <= entry_size);
reserved_space -= reserved_len;
if (reserved_space < 0) reserved_space = 0;
mdb_tassert(txn, reserved_space == 0);
}
if (reserved_space < mop_len) {
mop_len = reserved_space;
}
char do_write = env->me_freelist_written_start <= end && env->me_freelist_written_end >= start ||
(!end && env->me_freelist_written_end);
char do_write = env->me_freelist_written_start <= reserved_end && env->me_freelist_written_end >= start;
if (fl_writes[i++] != do_write) {
fprintf(stderr, "Do write of page does not match");
}
// if it is in the written range
if (env->me_freelist_written_start <= end && env->me_freelist_written_end >= start ||
// if we have collapsed to an empty list, but there was data written
(!end && env->me_freelist_written_end)) {
if (do_write) {
// we are in part of the range of the freelist that was written, so we actually need to save it
// if end == 0 it means that the length was probably truncated and we need to rewrite the length byte
if (save_end <= 0 && len > 0) len--; // leave off the last byte if we are ignoring it
Expand Down
1 change: 0 additions & 1 deletion src/writer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -593,7 +593,6 @@ Value EnvWrap::startWriting(const Napi::CallbackInfo& info) {
status = napi_create_object(n_env, &resource);
napi_value resource_name;
status = napi_create_string_latin1(n_env, "write", NAPI_AUTO_LENGTH, &resource_name);
//fprintf(stderr, "start write %p\n", instructionAddress);
auto worker = new WriteWorker(this->env, this, (uint32_t*) instructionAddress);
this->writeWorker = worker;
napi_create_reference(n_env, info[1].As<Function>(), 1, &worker->callback);
Expand Down

0 comments on commit 233bbc6

Please sign in to comment.