Skip to content

Commit

Permalink
Add transaction conditional for reseting and tracking last position i…
Browse files Browse the repository at this point in the history
…n freelist
  • Loading branch information
kriszyp committed Feb 15, 2024
1 parent 744fb7e commit 1ed38a8
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 11 deletions.
24 changes: 21 additions & 3 deletions dependencies/lmdb/libraries/liblmdb/mdb.c
Original file line number Diff line number Diff line change
Expand Up @@ -2728,7 +2728,7 @@ mdb_page_alloc(MDB_cursor *mc, int num, MDB_page **mp)
}
unsigned empty_entries = 0;
unsigned cache_size = env->me_block_size_cache[0];
pgno_t best_fit_start; // this is a block we will use if we don't find an exact fit
unsigned best_fit_start; // this is a block we will use if we don't find an exact fit
pgno_t best_fit_size;
for (op = MDB_FIRST;; op = MDB_NEXT) {
MDB_val key, data;
Expand Down Expand Up @@ -2758,8 +2758,9 @@ mdb_page_alloc(MDB_cursor *mc, int num, MDB_page **mp)
unsigned block_size = 0;
ssize_t entry;
empty_entries = 0;
mdb_midl_print(stderr, mop);
// TODO: Skip this on the first iteration, since we already checked the cache
for (i = 1; i <= mop_len; i++) {
for (i = env->me_freelist_position || 1; i <= mop_len; i++) {
entry = mop[i];
//fprintf(stderr, "pgno %u next would be %u\n", entry, block_start + block_size);
if (entry == 0) {
Expand All @@ -2783,6 +2784,12 @@ mdb_page_alloc(MDB_cursor *mc, int num, MDB_page **mp)
} else if (block_size < best_fit_size || best_fit_size == 0) {
best_fit_start = i - 1;
best_fit_size = block_size;
if (i == env->me_freelist_position) {
// TODO: Only if we are in the same transaction
// if we just wrote to this block and we are continuing on this block,
// skip ahead to using this block
goto continue_best_fit;
}
}
}
if (block_size > 0) {
Expand All @@ -2802,6 +2809,7 @@ mdb_page_alloc(MDB_cursor *mc, int num, MDB_page **mp)
//if (mop[i-n2] == pgno+n2)
// goto search_done;
}
env->me_freelist_position = 1;
i = 0;

if (op == MDB_FIRST) { /* 1st iteration */
Expand Down Expand Up @@ -2889,12 +2897,13 @@ mdb_page_alloc(MDB_cursor *mc, int num, MDB_page **mp)
if (mop != env->me_pghead) env->me_pghead = mop;
mop_len = mop[0];
}
continue_best_fit:
if (best_fit_start > 0) {
mop[best_fit_start] += num; // block length is a negative, so we add to it in order to subtract the amount we are using
if (mop[best_fit_start] == -1) mop[best_fit_start] = 0;
pgno = mop[best_fit_start + 1];
mop[best_fit_start + 1] += num;
env->me_freelist_position = pgno;
env->me_freelist_position = best_fit_start;
fprintf(stderr, "using best fit at %u size %u of %u\n", pgno, num, best_fit_size);
env->me_block_size_cache[best_fit_size] = 0; // clear this out of the cache (TODO: could move it)

Expand Down Expand Up @@ -3484,6 +3493,15 @@ mdb_txn_renew0(MDB_txn *txn)
if (ti) {
if (LOCK_MUTEX(rc, env, env->me_wmutex))
return rc;
// TODO: This should really be equality check and mt_txnid should be decremented if nothing was written
if (txn->mt_txnid < ti->mti_txnid) {
if (env->me_pghead) mdb_midl_free(env->me_pghead);
env->me_pghead = NULL;
env->me_pglast = 0;
env->me_freelist_position = 0;
// TODO: Free it first
env->me_block_size_cache = NULL;
}
txn->mt_txnid = ti->mti_txnid;
meta = env->me_metas[txn->mt_txnid & 1];
} else {
Expand Down
72 changes: 64 additions & 8 deletions dependencies/lmdb/libraries/liblmdb/midl.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,22 +106,54 @@ int mdb_midl_insert( MDB_IDL* ids_ref, MDB_ID id )
} else {
if (x > ids[0]) return -3; // at the end
ssize_t next_id = ids[x];
if (next_id < 0) next_id = ids[x + 1];
if (id - 1 == next_id && next_id > 0) {
// connected to next entry
ids[x]--; // increment negatively, as we have just expanded a block
// ids[x + 1] = id; // no need to adjust id, so since we are adding to the end of the block
return 0;
unsigned next_count = 1;
if (next_id < 0) {
next_count = -next_id;
next_id = ids[x + 1];
}
unsigned before = x; // this will end up pointing to an entry or zero right before a block of empty space
while (!ids[--before] && before > 0) {
// move past empty entries
}
if (id - next_count == next_id && next_id > 0) {
// connected to next entry
ssize_t count = next_count + 1;
// ids[x + 1] = id; // no need to adjust id, so since we are adding to the end of the block

if (before > 0) {
MDB_ID previous_id = before > 0 ? ids[before] : 0;
int previous_count = before > 1 ? -ids[before - 1] : 0;
if (previous_count < 1) previous_count = 1;
if (previous_id - 1 == id) {
// the block we just added to can now be connected to previous entry
count += previous_count;
if (previous_count > 1) {
ids[before - 1] = 0; // remove previous length
}
ids[before] = 0; // remove previous id
if (next_count == 1) {
// we can safely add the new count to the empty space
ids[x - 1] = -count; // update the count
return 0;
}
}
}
if (next_count > 1) {
ids[x] = -count; // update the count
} else if (ids[x - 1] == 0) {
ids[x - 1] = -2;
} else {
id = -2; // switching a single entry to a block size of 2
x--;
goto insert_id;
}
return 0;
}
if (before > 0) {
MDB_ID next_id = before > 0 ? ids[before] : 0;
MDB_ID previous_id = before > 0 ? ids[before] : 0;
int count = before > 1 ? -ids[before - 1] : 0;
if (count < 1) count = 1;
if (next_id - 1 == id) {
if (previous_id - 1 == id) {
// connected to previous entry
ids[before]--; // adjust the starting block to include this
if (count > 1) {
Expand Down Expand Up @@ -213,6 +245,7 @@ int mdb_midl_need( MDB_IDL *idp, unsigned num )
MDB_IDL new_ids;
if (!(new_ids = calloc(num, sizeof(MDB_ID))))
return ENOMEM;
fprintf(stderr, "Created new id list of size %u\n", num);
*new_ids++ = num - 2;
*new_ids = num - 2;
unsigned j = 1;
Expand All @@ -226,6 +259,7 @@ int mdb_midl_need( MDB_IDL *idp, unsigned num )
new_ids[j++] = entry;
if (entry < 0) new_ids[j++] = ids[++i]; // this was a block with a length
}
mdb_midl_free(ids);
// now shrink (or grow) back to appropriate size
num = (j + (j >> 3) + 22) & -16;
if (num > new_ids[0]) num = new_ids[0];
Expand All @@ -237,6 +271,28 @@ int mdb_midl_need( MDB_IDL *idp, unsigned num )
return 0;
}

int mdb_midl_print( FILE *fp, MDB_IDL ids )
{
if (ids == NULL) {
fprintf(fp, "freelist: NULL\n");
return 0;
}
unsigned i;
fprintf(fp, "freelist: %u: ", ids[0]);
for (i=1; i<=ids[0]; i++) {
ssize_t entry = ids[i];
if (entry < 0) {
fprintf(fp, "%li-%li ", ids[i+1], ids[i+1] - entry - 1);
i++;
} else if (ids[i] == 0) {
fprintf(fp, "_");
} else {
fprintf(fp, "%lu ", (unsigned long)ids[i]);
}
}
fprintf(fp, "\n");
return 0;
}
int mdb_midl_append( MDB_IDL *idp, MDB_ID id )
{
MDB_IDL ids = *idp;
Expand Down
3 changes: 3 additions & 0 deletions dependencies/lmdb/libraries/liblmdb/midl.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
#define _MDB_MIDL_H_

#include "lmdb.h"
#include <stdio.h>


#ifdef __cplusplus
extern "C" {
Expand Down Expand Up @@ -109,6 +111,7 @@ void mdb_midl_shrink(MDB_IDL *idp);
*/
int mdb_midl_need(MDB_IDL *idp, unsigned num);

int mdb_midl_print( FILE *fp, MDB_IDL ids );
/** Insert an ID into an IDL.
* @param[in,out] idp Address of the IDL to append to.
* @param[in] id The ID to append.
Expand Down

0 comments on commit 1ed38a8

Please sign in to comment.