unsigned int i;
txn->mt_u.dirty_list = malloc(sizeof(MDB_ID2)*MDB_IDL_UM_SIZE);
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);
/* silently ignore WRITEMAP when we're only getting read access */
flags &= ~MDB_WRITEMAP;
} 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)))))
rc = ENOMEM;
}
}
#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));
- *ids++ = MDB_IDL_UM_MAX;
+ MDB_IDL ids = malloc((num+2) * sizeof(MDB_ID));
+ if (ids)
+ *ids++ = num;
return ids;
}
void mdb_midl_free(MDB_IDL ids)
{
- free(ids-1);
+ if (ids)
+ free(ids-1);
}
int mdb_midl_shrink( MDB_IDL *idp )
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 )
{
MDB_IDL ids = *idp;
/* Too big? */
if (ids[0] >= ids[-1]) {
- MDB_IDL idn = ids-1;
- /* grow it */
- idn = realloc(idn, (*idn + MDB_IDL_UM_MAX + 1) * sizeof(MDB_ID));
- if (!idn)
- return -1;
- *idn++ += MDB_IDL_UM_MAX;
- ids = idn;
- *idp = ids;
+ if (mdb_midl_grow(idp, MDB_IDL_UM_MAX))
+ return ENOMEM;
+ ids = *idp;
}
ids[0]++;
ids[ids[0]] = id;
MDB_IDL ids = *idp;
/* Too big? */
if (ids[0] + app[0] >= ids[-1]) {
- MDB_IDL idn = ids-1;
- /* grow it */
- idn = realloc(idn, (*idn + app[-1]) * sizeof(MDB_ID));
- if (!idn)
- return -1;
- *idn++ += app[-1];
- ids = idn;
- *idp = ids;
+ if (mdb_midl_grow(idp, app[0]))
+ return ENOMEM;
+ ids = *idp;
}
memcpy(&ids[ids[0]+1], &app[1], app[0] * sizeof(MDB_ID));
ids[0] += app[0];
#endif
/** 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.
*/
-MDB_IDL mdb_midl_alloc(void);
+MDB_IDL mdb_midl_alloc(int num);
/** Free an IDL.
* @param[in] ids The IDL to free.
*/
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.
* @param[in,out] idp Address of the IDL to append to.
* @param[in] id The ID to append.