Increase the vector reserve as needed when pushing in new items

This commit is contained in:
Chris Robinson 2014-03-21 16:35:38 -07:00
parent 983fa4630a
commit 8c33b4d742
4 changed files with 21 additions and 25 deletions

View File

@ -701,13 +701,20 @@ void WriteUnlock(RWLock *lock)
} }
ALboolean vector_reserve(void *ptr, size_t orig_count, size_t base_size, size_t obj_count, size_t obj_size) ALboolean vector_reserve(void *ptr, size_t orig_count, size_t base_size, size_t obj_count, size_t obj_size, ALboolean exact)
{ {
if(orig_count < obj_count) if(orig_count < obj_count)
{ {
vector_ *vecptr = ptr; vector_ *vecptr = ptr;
void *temp; void *temp;
/* Use the next power-of-2 size if we don't need to allocate the exact
* amount. This is preferred when regularly increasing the vector since
* it means fewer reallocations. Though it means it also wastes some
* memory. */
if(exact == AL_FALSE)
obj_count = NextPowerOf2(obj_count);
/* Need to be explicit with the caller type's base size, because it /* Need to be explicit with the caller type's base size, because it
* could have extra padding before the start of the array (that is, * could have extra padding before the start of the array (that is,
* sizeof(*vector_) may not equal base_size). */ * sizeof(*vector_) may not equal base_size). */

View File

@ -380,14 +380,11 @@ static void GenModList_insertGen(GenModList *self, const Generator *gen, ALboole
gen->mGenerator == 58)) gen->mGenerator == 58))
return; return;
if(VECTOR_RESERVE(self->gens, NextPowerOf2(VECTOR_SIZE(self->gens)+1)) == AL_FALSE) if(VECTOR_PUSH_BACK(self->gens, *gen) == AL_FALSE)
{ {
ERR("Failed to increase generator storage to %d elements (from %d)\n", ERR("Failed to insert generator (from %d elements)\n", VECTOR_SIZE(self->gens));
NextPowerOf2(VECTOR_SIZE(self->gens)+1), VECTOR_CAPACITY(self->gens));
return; return;
} }
VECTOR_PUSH_BACK(self->gens, *gen);
} }
static void GenModList_accumGen(GenModList *self, const Generator *gen) static void GenModList_accumGen(GenModList *self, const Generator *gen)
{ {
@ -412,14 +409,11 @@ static void GenModList_accumGen(GenModList *self, const Generator *gen)
} }
} }
if(VECTOR_RESERVE(self->gens, NextPowerOf2(VECTOR_SIZE(self->gens)+1)) == AL_FALSE) if(VECTOR_PUSH_BACK(self->gens, *gen) == AL_FALSE)
{ {
ERR("Failed to increase generator storage to %d elements (from %d)\n", ERR("Failed to insert generator (from %d elements)\n", VECTOR_SIZE(self->gens));
NextPowerOf2(VECTOR_SIZE(self->gens)+1), VECTOR_CAPACITY(self->gens));
return; return;
} }
VECTOR_PUSH_BACK(self->gens, *gen);
if(gen->mGenerator < 60) if(gen->mGenerator < 60)
VECTOR_BACK(self->gens).mAmount += DefaultGenValue[gen->mGenerator]; VECTOR_BACK(self->gens).mAmount += DefaultGenValue[gen->mGenerator];
} }
@ -438,14 +432,11 @@ static void GenModList_insertMod(GenModList *self, const Modulator *mod)
} }
} }
if(VECTOR_RESERVE(self->mods, NextPowerOf2(VECTOR_SIZE(self->mods)+1)) == AL_FALSE) if(VECTOR_PUSH_BACK(self->mods, *mod) == AL_FALSE)
{ {
ERR("Failed to increase modulator storage to %d elements (from %d)\n", ERR("Failed to insert modulator (from %d elements)\n", VECTOR_SIZE(self->mods));
NextPowerOf2(VECTOR_SIZE(self->mods)+1), VECTOR_CAPACITY(self->mods));
return; return;
} }
VECTOR_PUSH_BACK(self->mods, *mod);
} }
static void GenModList_accumMod(GenModList *self, const Modulator *mod) static void GenModList_accumMod(GenModList *self, const Modulator *mod)
{ {
@ -461,14 +452,12 @@ static void GenModList_accumMod(GenModList *self, const Modulator *mod)
} }
} }
if(VECTOR_RESERVE(self->mods, NextPowerOf2(VECTOR_SIZE(self->mods)+1)) == AL_FALSE) if(VECTOR_PUSH_BACK(self->mods, *mod) == AL_FALSE)
{ {
ERR("Failed to increase modulator storage to %d elements (from %d)\n", ERR("Failed to insert modulator (from %d elements)\n", VECTOR_SIZE(self->mods));
NextPowerOf2(VECTOR_SIZE(self->mods)+1), VECTOR_CAPACITY(self->mods));
return; return;
} }
VECTOR_PUSH_BACK(self->mods, *mod);
if(mod->mSrcOp == 0x0502 && mod->mDstOp == 48 && mod->mAmtSrcOp == 0 && mod->mTransOp == 0) if(mod->mSrcOp == 0x0502 && mod->mDstOp == 48 && mod->mAmtSrcOp == 0 && mod->mTransOp == 0)
VECTOR_BACK(self->mods).mAmount += 960; VECTOR_BACK(self->mods).mAmount += 960;
else if(mod->mSrcOp == 0x0102 && mod->mDstOp == 8 && mod->mAmtSrcOp == 0 && mod->mTransOp == 0) else if(mod->mSrcOp == 0x0102 && mod->mDstOp == 8 && mod->mAmtSrcOp == 0 && mod->mTransOp == 0)

View File

@ -21,8 +21,8 @@ typedef struct vector__s {
#define VECTOR_DEINIT(_x) do { free(_x); _x = NULL; } while(0) #define VECTOR_DEINIT(_x) do { free(_x); _x = NULL; } while(0)
/* Helper to increase a vector's reserve. Do not call directly. */ /* Helper to increase a vector's reserve. Do not call directly. */
ALboolean vector_reserve(void *ptr, size_t orig_count, size_t base_size, size_t obj_count, size_t obj_size); ALboolean vector_reserve(void *ptr, size_t orig_count, size_t base_size, size_t obj_count, size_t obj_size, ALboolean exact);
#define VECTOR_RESERVE(_x, _c) (vector_reserve(&(_x), (_x)->Capacity, sizeof(*(_x)), (_c), sizeof((_x)->Data[0]))) #define VECTOR_RESERVE(_x, _c) (vector_reserve(&(_x), (_x)->Capacity, sizeof(*(_x)), (_c), sizeof((_x)->Data[0]), AL_TRUE))
#define VECTOR_CAPACITY(_x) ((const ALsizei)(_x)->Capacity) #define VECTOR_CAPACITY(_x) ((const ALsizei)(_x)->Capacity)
#define VECTOR_SIZE(_x) ((const ALsizei)(_x)->Size) #define VECTOR_SIZE(_x) ((const ALsizei)(_x)->Size)
@ -30,8 +30,8 @@ ALboolean vector_reserve(void *ptr, size_t orig_count, size_t base_size, size_t
#define VECTOR_ITER_BEGIN(_x) ((_x)->Data) #define VECTOR_ITER_BEGIN(_x) ((_x)->Data)
#define VECTOR_ITER_END(_x) ((_x)->Data + (_x)->Size) #define VECTOR_ITER_END(_x) ((_x)->Data + (_x)->Size)
/* NOTE: The caller must ensure enough space is reserved before pushing in new objects. */ #define VECTOR_PUSH_BACK(_x, _obj) (vector_reserve(&(_x), (_x)->Capacity, sizeof(*(_x)), (_x)->Size+1, sizeof((_x)->Data[0]), AL_FALSE) && \
#define VECTOR_PUSH_BACK(_x, _obj) ((void)((_x)->Data[(_x)->Size++] = (_obj))) (((_x)->Data[(_x)->Size++] = (_obj)),AL_TRUE))
#define VECTOR_POP_BACK(_x) ((void)((_x)->Size--)) #define VECTOR_POP_BACK(_x) ((void)((_x)->Size--))
#define VECTOR_BACK(_x) ((_x)->Data[(_x)->Size-1]) #define VECTOR_BACK(_x) ((_x)->Data[(_x)->Size-1])

View File

@ -386,7 +386,7 @@ static ALvoid RemoveEffectSlotArray(ALCcontext *context, ALeffectslot *slot)
{ {
if(*slotlist == slot) if(*slotlist == slot)
{ {
*slotlist = *(--slotlistend); *slotlist = VECTOR_BACK(context->ActiveAuxSlots);
VECTOR_POP_BACK(context->ActiveAuxSlots); VECTOR_POP_BACK(context->ActiveAuxSlots);
break; break;
} }