Refactor mdb_midl_append, add mdb_midl_grow()

This commit is contained in:
Howard Chu 2013-05-09 17:27:29 -07:00
parent 2d6aed7537
commit 66c839f029
3 changed files with 36 additions and 24 deletions

View File

@ -1941,7 +1941,7 @@ mdb_txn_begin(MDB_env *env, MDB_txn *parent, unsigned int flags, MDB_txn **ret)
unsigned int i; unsigned int i;
txn->mt_u.dirty_list = malloc(sizeof(MDB_ID2)*MDB_IDL_UM_SIZE); txn->mt_u.dirty_list = malloc(sizeof(MDB_ID2)*MDB_IDL_UM_SIZE);
if (!txn->mt_u.dirty_list || if (!txn->mt_u.dirty_list ||
!(txn->mt_free_pgs = mdb_midl_alloc())) !(txn->mt_free_pgs = mdb_midl_alloc(MDB_IDL_UM_MAX)))
{ {
free(txn->mt_u.dirty_list); free(txn->mt_u.dirty_list);
free(txn); free(txn);
@ -3472,7 +3472,7 @@ mdb_env_open(MDB_env *env, const char *path, unsigned int flags, mdb_mode_t mode
/* silently ignore WRITEMAP when we're only getting read access */ /* silently ignore WRITEMAP when we're only getting read access */
flags &= ~MDB_WRITEMAP; flags &= ~MDB_WRITEMAP;
} else { } else {
if (!((env->me_free_pgs = mdb_midl_alloc()) && if (!((env->me_free_pgs = mdb_midl_alloc(MDB_IDL_UM_MAX)) &&
(env->me_dirty_list = calloc(MDB_IDL_UM_SIZE, sizeof(MDB_ID2))))) (env->me_dirty_list = calloc(MDB_IDL_UM_SIZE, sizeof(MDB_ID2)))))
rc = ENOMEM; rc = ENOMEM;
} }

View File

@ -117,16 +117,18 @@ int mdb_midl_insert( MDB_IDL ids, MDB_ID id )
} }
#endif #endif
MDB_IDL mdb_midl_alloc(void) MDB_IDL mdb_midl_alloc(int num)
{ {
MDB_IDL ids = malloc((MDB_IDL_UM_MAX+1) * sizeof(MDB_ID)); MDB_IDL ids = malloc((num+2) * sizeof(MDB_ID));
*ids++ = MDB_IDL_UM_MAX; if (ids)
*ids++ = num;
return ids; return ids;
} }
void mdb_midl_free(MDB_IDL ids) void mdb_midl_free(MDB_IDL ids)
{ {
free(ids-1); if (ids)
free(ids-1);
} }
int mdb_midl_shrink( MDB_IDL *idp ) int mdb_midl_shrink( MDB_IDL *idp )
@ -141,19 +143,26 @@ int mdb_midl_shrink( MDB_IDL *idp )
return 0; return 0;
} }
int mdb_midl_grow( MDB_IDL *idp, int num )
{
MDB_IDL idn = *idp-1;
/* grow it */
idn = realloc(idn, (*idn + num + 2) * sizeof(MDB_ID));
if (!idn)
return ENOMEM;
*idn++ += num;
*idp = idn;
return 0;
}
int mdb_midl_append( MDB_IDL *idp, MDB_ID id ) int mdb_midl_append( MDB_IDL *idp, MDB_ID id )
{ {
MDB_IDL ids = *idp; MDB_IDL ids = *idp;
/* Too big? */ /* Too big? */
if (ids[0] >= ids[-1]) { if (ids[0] >= ids[-1]) {
MDB_IDL idn = ids-1; if (mdb_midl_grow(idp, MDB_IDL_UM_MAX))
/* grow it */ return ENOMEM;
idn = realloc(idn, (*idn + MDB_IDL_UM_MAX + 1) * sizeof(MDB_ID)); ids = *idp;
if (!idn)
return -1;
*idn++ += MDB_IDL_UM_MAX;
ids = idn;
*idp = ids;
} }
ids[0]++; ids[0]++;
ids[ids[0]] = id; ids[ids[0]] = id;
@ -165,14 +174,9 @@ int mdb_midl_append_list( MDB_IDL *idp, MDB_IDL app )
MDB_IDL ids = *idp; MDB_IDL ids = *idp;
/* Too big? */ /* Too big? */
if (ids[0] + app[0] >= ids[-1]) { if (ids[0] + app[0] >= ids[-1]) {
MDB_IDL idn = ids-1; if (mdb_midl_grow(idp, app[0]))
/* grow it */ return ENOMEM;
idn = realloc(idn, (*idn + app[-1]) * sizeof(MDB_ID)); ids = *idp;
if (!idn)
return -1;
*idn++ += app[-1];
ids = idn;
*idp = ids;
} }
memcpy(&ids[ids[0]+1], &app[1], app[0] * sizeof(MDB_ID)); memcpy(&ids[ids[0]+1], &app[1], app[0] * sizeof(MDB_ID));
ids[0] += app[0]; ids[0] += app[0];

View File

@ -115,10 +115,10 @@ int mdb_midl_insert( MDB_IDL ids, MDB_ID id );
#endif #endif
/** Allocate an IDL. /** Allocate an IDL.
* Allocates memory for an IDL of a default size. * Allocates memory for an IDL of the given size.
* @return IDL on success, NULL on failure. * @return IDL on success, NULL on failure.
*/ */
MDB_IDL mdb_midl_alloc(void); MDB_IDL mdb_midl_alloc(int num);
/** Free an IDL. /** Free an IDL.
* @param[in] ids The IDL to free. * @param[in] ids The IDL to free.
@ -132,6 +132,14 @@ void mdb_midl_free(MDB_IDL ids);
*/ */
int mdb_midl_shrink(MDB_IDL *idp); int mdb_midl_shrink(MDB_IDL *idp);
/** Grow an IDL.
* Add room for num additional elements.
* @param[in,out] idp Address of the IDL to grow.
* @param[i] num Number of elements to add.
* @return 0 on success, -1 on failure.
*/
int mdb_midl_grow(MDB_IDL *idp, int num);
/** Append an ID onto an IDL. /** Append an ID onto an IDL.
* @param[in,out] idp Address of the IDL to append to. * @param[in,out] idp Address of the IDL to append to.
* @param[in] id The ID to append. * @param[in] id The ID to append.