mirror of
https://github.com/MariaDB/server.git
synced 2025-02-02 03:51:50 +01:00
Closes #912
toku_db_set_* (the dbt setting functions) no longer require atomicity for ENOMEM cases. Also, in the case of realloc, we only alloc new memory if the new size is larger than the old size, or the new size is less than half of the old size. Code has some simplifications due to lesser atomicity requirements. Modified src/tests/test_db_dbt_mem_behavior.c to take into account that DB_DBT_REALLOC now uses the ulen field. git-svn-id: file:///svn/tokudb@4504 c7de825b-a66e-492c-adef-691d508d4ae1
This commit is contained in:
parent
fe3cd46d32
commit
acf688ef2e
2 changed files with 64 additions and 43 deletions
98
newbrt/ybt.c
98
newbrt/ybt.c
|
@ -16,7 +16,7 @@ DBT *toku_fill_dbt(DBT *dbt, bytevec k, ITEMLEN len) {
|
|||
return dbt;
|
||||
}
|
||||
|
||||
static inline int dbt_set_preprocess(DBT* ybt, ITEMLEN len, void** staticptrp, void** tmp_data, BOOL input_disposable) {
|
||||
static inline int dbt_set_preprocess(DBT* ybt, ITEMLEN len, void** staticptrp) {
|
||||
int r = ENOSYS;
|
||||
if (ybt) {
|
||||
if (ybt->flags==DB_DBT_USERMEM) {
|
||||
|
@ -26,39 +26,61 @@ static inline int dbt_set_preprocess(DBT* ybt, ITEMLEN len, void** staticptrp, v
|
|||
goto cleanup;
|
||||
}
|
||||
}
|
||||
else if (ybt->flags==DB_DBT_MALLOC || ybt->flags==DB_DBT_REALLOC || ybt->flags==0) {
|
||||
if (ybt->flags==0 && staticptrp==NULL) { r = -1; goto cleanup; }
|
||||
if (!input_disposable) {
|
||||
*tmp_data = toku_malloc(len);
|
||||
if (!*tmp_data) { r = errno; goto cleanup; }
|
||||
}
|
||||
else if (ybt->flags==0) {
|
||||
if (!staticptrp) { r = -1; goto cleanup; }
|
||||
}
|
||||
else if (ybt->flags!=DB_DBT_MALLOC && ybt->flags!=DB_DBT_REALLOC) {
|
||||
r = EINVAL; goto cleanup;
|
||||
}
|
||||
else { r = EINVAL; goto cleanup; }
|
||||
}
|
||||
r = 0;
|
||||
cleanup:
|
||||
return r;
|
||||
}
|
||||
|
||||
static inline void dbt_set_copy(DBT* ybt, bytevec* datap, ITEMLEN len, void** staticptrp, void** tmp_data, BOOL input_disposable) {
|
||||
static inline int dbt_set_copy(DBT* ybt, bytevec* datap, ITEMLEN len, void** staticptrp, BOOL input_disposable) {
|
||||
if (ybt) {
|
||||
bytevec data = *datap;
|
||||
if (ybt->flags==DB_DBT_USERMEM) input_disposable = FALSE;
|
||||
else if (input_disposable) {
|
||||
*tmp_data = (void*)data;
|
||||
*datap = NULL;
|
||||
if (ybt->flags==DB_DBT_USERMEM) {
|
||||
if ((ybt->size=len) > 0) memcpy(ybt->data, *datap, (size_t)len);
|
||||
return 0;
|
||||
}
|
||||
if (ybt->flags==DB_DBT_REALLOC && ybt->data) toku_free(ybt->data);
|
||||
else if (ybt->flags==0) {
|
||||
if (*staticptrp) toku_free(*staticptrp);
|
||||
*staticptrp = *tmp_data;
|
||||
void* tempdata;
|
||||
BOOL do_malloc = TRUE;
|
||||
|
||||
if (input_disposable) {
|
||||
tempdata = (void*)*datap;
|
||||
do_malloc = FALSE;
|
||||
}
|
||||
if (ybt->flags!=DB_DBT_USERMEM) {
|
||||
if (ybt->flags!=0 || len>0) ybt->data = *tmp_data;
|
||||
else ybt->data = NULL;
|
||||
else if (ybt->flags==DB_DBT_REALLOC) {
|
||||
if (ybt->data && ybt->ulen>=len && ybt->ulen/2<=len) {
|
||||
tempdata = ybt->data;
|
||||
do_malloc = FALSE;
|
||||
}
|
||||
}
|
||||
if ((ybt->size = len) > 0 && !input_disposable) memcpy(ybt->data, data, (size_t)len);
|
||||
//Malloc new buffer
|
||||
if (do_malloc) {
|
||||
tempdata = toku_malloc(len);
|
||||
if (!tempdata) return errno;
|
||||
}
|
||||
if (input_disposable || do_malloc) {
|
||||
//Set ulen
|
||||
if (ybt->flags==DB_DBT_REALLOC) ybt->ulen = len;
|
||||
//Freeing
|
||||
if (ybt->flags==DB_DBT_REALLOC && ybt->data) toku_free(ybt->data);
|
||||
if (ybt->flags==0) {
|
||||
if (*staticptrp) toku_free(*staticptrp);
|
||||
//Set static pointer
|
||||
*staticptrp = tempdata;
|
||||
}
|
||||
}
|
||||
//Set ybt->data
|
||||
if (ybt->flags!=0 || len>0) ybt->data = tempdata;
|
||||
else ybt->data = NULL;
|
||||
//Set ybt->size and memcpy
|
||||
if ((ybt->size=len) > 0 && !input_disposable) memcpy(ybt->data, *datap, (size_t)len);
|
||||
if (input_disposable) *datap = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Atomically set three dbts, such that they either both succeed, or
|
||||
|
@ -68,27 +90,19 @@ int toku_dbt_set_three_values(
|
|||
DBT* ybt2, bytevec* ybt2_data, ITEMLEN ybt2_len, void** ybt2_staticptrp, BOOL ybt2_disposable,
|
||||
DBT* ybt3, bytevec* ybt3_data, ITEMLEN ybt3_len, void** ybt3_staticptrp, BOOL ybt3_disposable) {
|
||||
int r = ENOSYS;
|
||||
void* tmp_ybt1_data = NULL;
|
||||
void* tmp_ybt2_data = NULL;
|
||||
void* tmp_ybt3_data = NULL;
|
||||
|
||||
/* Do all mallocs and check for all possible errors. */
|
||||
if ((r = dbt_set_preprocess(ybt1, ybt1_len, ybt1_staticptrp, &tmp_ybt1_data, ybt1_disposable))) goto cleanup;
|
||||
if ((r = dbt_set_preprocess(ybt2, ybt2_len, ybt2_staticptrp, &tmp_ybt2_data, ybt2_disposable))) goto cleanup;
|
||||
if ((r = dbt_set_preprocess(ybt3, ybt3_len, ybt3_staticptrp, &tmp_ybt3_data, ybt3_disposable))) goto cleanup;
|
||||
if ((r = dbt_set_preprocess(ybt1, ybt1_len, ybt1_staticptrp))) goto cleanup;
|
||||
if ((r = dbt_set_preprocess(ybt2, ybt2_len, ybt2_staticptrp))) goto cleanup;
|
||||
if ((r = dbt_set_preprocess(ybt3, ybt3_len, ybt3_staticptrp))) goto cleanup;
|
||||
|
||||
/* Copy/modify atomically the dbts. */
|
||||
dbt_set_copy(ybt1, ybt1_data, ybt1_len, ybt1_staticptrp, &tmp_ybt1_data, ybt1_disposable);
|
||||
dbt_set_copy(ybt2, ybt2_data, ybt2_len, ybt2_staticptrp, &tmp_ybt2_data, ybt2_disposable);
|
||||
dbt_set_copy(ybt3, ybt3_data, ybt3_len, ybt3_staticptrp, &tmp_ybt3_data, ybt3_disposable);
|
||||
if ((r = dbt_set_copy(ybt1, ybt1_data, ybt1_len, ybt1_staticptrp, ybt1_disposable))) goto cleanup;
|
||||
if ((r = dbt_set_copy(ybt2, ybt2_data, ybt2_len, ybt2_staticptrp, ybt2_disposable))) goto cleanup;
|
||||
if ((r = dbt_set_copy(ybt3, ybt3_data, ybt3_len, ybt3_staticptrp, ybt3_disposable))) goto cleanup;
|
||||
|
||||
r = 0;
|
||||
cleanup:
|
||||
if (r!=0) {
|
||||
if (tmp_ybt1_data) toku_free(tmp_ybt1_data);
|
||||
if (tmp_ybt2_data) toku_free(tmp_ybt2_data);
|
||||
if (tmp_ybt3_data) toku_free(tmp_ybt3_data);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -102,12 +116,12 @@ int toku_dbt_set_two_values(
|
|||
void* tmp_ybt2_data = NULL;
|
||||
|
||||
/* Do all mallocs and check for all possible errors. */
|
||||
if ((r = dbt_set_preprocess(ybt1, ybt1_len, ybt1_staticptrp, &tmp_ybt1_data, ybt1_disposable))) goto cleanup;
|
||||
if ((r = dbt_set_preprocess(ybt2, ybt2_len, ybt2_staticptrp, &tmp_ybt2_data, ybt2_disposable))) goto cleanup;
|
||||
if ((r = dbt_set_preprocess(ybt1, ybt1_len, ybt1_staticptrp))) goto cleanup;
|
||||
if ((r = dbt_set_preprocess(ybt2, ybt2_len, ybt2_staticptrp))) goto cleanup;
|
||||
|
||||
/* Copy/modify atomically the dbts. */
|
||||
dbt_set_copy(ybt1, ybt1_data, ybt1_len, ybt1_staticptrp, &tmp_ybt1_data, ybt1_disposable);
|
||||
dbt_set_copy(ybt2, ybt2_data, ybt2_len, ybt2_staticptrp, &tmp_ybt2_data, ybt2_disposable);
|
||||
if ((r = dbt_set_copy(ybt1, ybt1_data, ybt1_len, ybt1_staticptrp, ybt1_disposable))) goto cleanup;
|
||||
if ((r = dbt_set_copy(ybt2, ybt2_data, ybt2_len, ybt2_staticptrp, ybt2_disposable))) goto cleanup;
|
||||
|
||||
r = 0;
|
||||
cleanup:
|
||||
|
@ -123,10 +137,10 @@ int toku_dbt_set_value(DBT* ybt1, bytevec* ybt1_data, ITEMLEN ybt1_len, void** y
|
|||
void* tmp_ybt1_data = NULL;
|
||||
|
||||
/* Do all mallocs and check for all possible errors. */
|
||||
if ((r = dbt_set_preprocess(ybt1, ybt1_len, ybt1_staticptrp, &tmp_ybt1_data, ybt1_disposable))) goto cleanup;
|
||||
if ((r = dbt_set_preprocess(ybt1, ybt1_len, ybt1_staticptrp))) goto cleanup;
|
||||
|
||||
/* Copy/modify atomically the dbts. */
|
||||
dbt_set_copy(ybt1, ybt1_data, ybt1_len, ybt1_staticptrp, &tmp_ybt1_data, ybt1_disposable);
|
||||
if ((r = dbt_set_copy(ybt1, ybt1_data, ybt1_len, ybt1_staticptrp, ybt1_disposable))) goto cleanup;
|
||||
|
||||
r = 0;
|
||||
cleanup:
|
||||
|
|
|
@ -128,7 +128,14 @@ int main(int argc, const char *argv[]) {
|
|||
}
|
||||
|
||||
assert(!was_truncated);
|
||||
assert(!ulen_changed);
|
||||
|
||||
BOOL ulen_should_change = FALSE;
|
||||
#if defined(USE_TDB)
|
||||
if (flags[j] == DB_DBT_REALLOC) {
|
||||
ulen_should_change = old_ulen < sizeof(DATA);
|
||||
}
|
||||
#endif
|
||||
assert(ulen_should_change == ulen_changed);
|
||||
assert(size_full);
|
||||
assert(clone == !small_buffer);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue