Tweak tool IDL cache, use MDB_MULTIPLE

This commit is contained in:
Howard Chu 2011-10-03 11:29:04 -07:00
parent 8a8fb76cca
commit 9725bc475f

View File

@ -38,7 +38,11 @@ typedef struct mdb_tool_idl_cache {
mdb_tool_idl_cache_entry *head, *tail; mdb_tool_idl_cache_entry *head, *tail;
ID first, last; ID first, last;
int count; int count;
short offset;
short flags;
} mdb_tool_idl_cache; } mdb_tool_idl_cache;
#define WAS_FOUND 0x01
#define WAS_RANGE 0x02
static mdb_tool_idl_cache_entry *mdb_tool_idl_free_list; static mdb_tool_idl_cache_entry *mdb_tool_idl_free_list;
static Avlnode *mdb_tool_roots[MDB_INDICES]; static Avlnode *mdb_tool_roots[MDB_INDICES];
@ -924,7 +928,7 @@ static int
mdb_tool_idl_flush_one( MDB_cursor *mc, mdb_tool_idl_cache *ic ) mdb_tool_idl_flush_one( MDB_cursor *mc, mdb_tool_idl_cache *ic )
{ {
mdb_tool_idl_cache_entry *ice; mdb_tool_idl_cache_entry *ice;
MDB_val key, data; MDB_val key, data[2];
int i, rc; int i, rc;
ID id, nid; ID id, nid;
@ -936,54 +940,56 @@ mdb_tool_idl_flush_one( MDB_cursor *mc, mdb_tool_idl_cache *ic )
key.mv_data = ic->kstr.bv_val; key.mv_data = ic->kstr.bv_val;
key.mv_size = ic->kstr.bv_len; key.mv_size = ic->kstr.bv_len;
rc = mdb_cursor_get( mc, &key, &data, MDB_SET ); if ( ic->count > MDB_IDL_DB_SIZE ) {
/* If key already exists and we're writing a range... */ while ( ic->flags & WAS_FOUND ) {
if ( rc == 0 && ic->count > MDB_IDL_DB_SIZE ) { rc = mdb_cursor_get( mc, &key, data, MDB_SET );
nid = *(ID *)data.mv_data; if ( rc ) {
/* If it's not currently a range, must delete old info */ /* FIXME: find out why this happens */
if ( nid ) { ic->flags = 0;
ic->first = nid; break;
mdb_cursor_del( mc, MDB_NODUPDATA ); }
if ( ic->flags & WAS_RANGE ) {
/* Skip lo */
rc = mdb_cursor_get( mc, &key, data, MDB_NEXT_DUP );
goto setrange; /* Get hi */
} else { rc = mdb_cursor_get( mc, &key, data, MDB_NEXT_DUP );
/* Skip lo */
rc = mdb_cursor_get( mc, &key, &data, MDB_NEXT_DUP );
/* Get hi */ /* Store range hi */
rc = mdb_cursor_get( mc, &key, &data, MDB_NEXT_DUP ); data[0].mv_data = &ic->last;
rc = mdb_cursor_put( mc, &key, data, MDB_CURRENT );
/* Store range hi */ } else {
data.mv_data = &ic->last; /* Delete old data, replace with range */
rc = mdb_cursor_put( mc, &key, &data, MDB_CURRENT ); ic->first = *(ID *)data[0].mv_data;
mdb_cursor_del( mc, MDB_NODUPDATA );
}
break;
} }
rc = 0; if ( !(ic->flags & WAS_RANGE)) {
} else if ( rc && rc != MDB_NOTFOUND ) { /* range, didn't exist before */
rc = -1; nid = 0;
} else if ( ic->count > MDB_IDL_DB_SIZE ) { data[0].mv_size = sizeof(ID);
/* range, didn't exist before */ data[0].mv_data = &nid;
setrange: rc = mdb_cursor_put( mc, &key, data, 0 );
nid = 0;
data.mv_size = sizeof(ID);
data.mv_data = &nid;
rc = mdb_cursor_put( mc, &key, &data, 0 );
if ( rc == 0 ) {
data.mv_data = &ic->first;
rc = mdb_cursor_put( mc, &key, &data, 0 );
if ( rc == 0 ) { if ( rc == 0 ) {
data.mv_data = &ic->last; data[0].mv_data = &ic->first;
rc = mdb_cursor_put( mc, &key, &data, 0 ); rc = mdb_cursor_put( mc, &key, data, 0 );
if ( rc == 0 ) {
data[0].mv_data = &ic->last;
rc = mdb_cursor_put( mc, &key, data, 0 );
}
}
if ( rc ) {
rc = -1;
} }
} }
if ( rc ) {
rc = -1;
}
} else { } else {
/* Normal write */
int n; int n;
data.mv_size = sizeof(ID); data[0].mv_size = sizeof(ID);
/* Just a normal write */
rc = 0; rc = 0;
i = ic->offset;
for ( ice = ic->head, n=0; ice; ice = ice->next, n++ ) { for ( ice = ic->head, n=0; ice; ice = ice->next, n++ ) {
int end; int end;
if ( ice->next ) { if ( ice->next ) {
@ -993,20 +999,15 @@ setrange:
if ( !end ) if ( !end )
end = IDBLOCK; end = IDBLOCK;
} }
for ( i=0; i<end; i++ ) { data[1].mv_size = end - i;
if ( !ice->ids[i] ) continue; data[0].mv_data = &ice->ids[i];
data.mv_data = &ice->ids[i]; i = 0;
rc = mdb_cursor_put( mc, &key, &data, MDB_NODUPDATA|MDB_APPEND ); rc = mdb_cursor_put( mc, &key, data, MDB_NODUPDATA|MDB_APPEND|MDB_MULTIPLE );
if ( rc ) {
if ( rc == MDB_KEYEXIST ) {
rc = 0;
continue;
}
rc = -1;
break;
}
}
if ( rc ) { if ( rc ) {
if ( rc == MDB_KEYEXIST ) {
rc = 0;
continue;
}
rc = -1; rc = -1;
break; break;
} }
@ -1064,7 +1065,7 @@ int mdb_tool_idl_add(
MDB_dbi dbi; MDB_dbi dbi;
mdb_tool_idl_cache *ic, itmp; mdb_tool_idl_cache *ic, itmp;
mdb_tool_idl_cache_entry *ice; mdb_tool_idl_cache_entry *ice;
int i, rc; int i, rc, lcount;
dbi = mdb_cursor_dbi(mc); dbi = mdb_cursor_dbi(mc);
for (i=0; keys[i].bv_val; i++) { for (i=0; keys[i].bv_val; i++) {
@ -1084,24 +1085,28 @@ int mdb_tool_idl_add(
ic->head = ic->tail = NULL; ic->head = ic->tail = NULL;
ic->last = 0; ic->last = 0;
ic->count = 0; ic->count = 0;
ic->offset = 0;
ic->flags = 0;
tavl_insert( (Avlnode **)&mdb_tool_roots[dbi], ic, mdb_tool_idl_cmp, tavl_insert( (Avlnode **)&mdb_tool_roots[dbi], ic, mdb_tool_idl_cmp,
avl_dup_error ); avl_dup_error );
/* load existing key count here */ /* load existing key count here */
key.mv_size = keys[i].bv_len; key.mv_size = keys[i].bv_len;
key.mv_data = keys[i].bv_val; key.mv_data = keys[i].bv_val;
data.mv_size = sizeof( ID );
data.mv_data = &nid;
rc = mdb_cursor_get( mc, &key, &data, MDB_SET ); rc = mdb_cursor_get( mc, &key, &data, MDB_SET );
if ( rc == 0 ) { if ( rc == 0 ) {
ic->flags |= WAS_FOUND;
nid = *(ID *)data.mv_data;
if ( nid == 0 ) { if ( nid == 0 ) {
ic->count = MDB_IDL_DB_SIZE+1; ic->count = MDB_IDL_DB_SIZE+1;
ic->flags |= WAS_RANGE;
} else { } else {
size_t count; size_t count;
mdb_cursor_count( mc, &count ); mdb_cursor_count( mc, &count );
ic->count = count; ic->count = count;
ic->first = nid; ic->first = nid;
ic->offset = count & (IDBLOCK-1);
} }
} }
} }
@ -1124,7 +1129,8 @@ int mdb_tool_idl_add(
continue; continue;
} }
/* No free block, create that too */ /* No free block, create that too */
if ( !ic->tail || ( ic->count & (IDBLOCK-1)) == 0) { lcount = ic->count & (IDBLOCK-1);
if ( !ic->tail || lcount == 0) {
ice = NULL; ice = NULL;
if ( mdb_tool_idl_free_list ) { if ( mdb_tool_idl_free_list ) {
ice = mdb_tool_idl_free_list; ice = mdb_tool_idl_free_list;
@ -1133,7 +1139,7 @@ int mdb_tool_idl_add(
if ( !ice ) { if ( !ice ) {
ice = ch_malloc( sizeof( mdb_tool_idl_cache_entry )); ice = ch_malloc( sizeof( mdb_tool_idl_cache_entry ));
} }
memset( ice, 0, sizeof( *ice )); ice->next = NULL;
if ( !ic->head ) { if ( !ic->head ) {
ic->head = ice; ic->head = ice;
} else { } else {
@ -1144,7 +1150,8 @@ int mdb_tool_idl_add(
ic->first = id; ic->first = id;
} }
ice = ic->tail; ice = ic->tail;
ice->ids[ ic->count & (IDBLOCK-1) ] = id; if (!lcount || ice->ids[lcount-1] != id)
ice->ids[lcount] = id;
ic->count++; ic->count++;
} }