4jcraft/Minecraft.World/Util/IntCache.cpp
2026-03-13 17:06:56 -05:00

141 lines
4.1 KiB
C++

#include "../Platform/stdafx.h"
#include "IntCache.h"
unsigned int IntCache::tlsIdx = TlsAlloc();
void IntCache::CreateNewThreadStorage() {
ThreadStorage* tls = new ThreadStorage();
TlsSetValue(tlsIdx, (void*)tls);
tls->maxSize = TINY_CUTOFF;
}
IntCache::ThreadStorage::~ThreadStorage() {
for (unsigned int i = 0; i < tcache.size(); i++) {
delete[] tcache[i].data;
}
for (unsigned int i = 0; i < tallocated.size(); i++) {
delete[] tallocated[i].data;
}
for (unsigned int i = 0; i < cache.size(); i++) {
delete[] cache[i].data;
}
for (unsigned int i = 0; i < allocated.size(); i++) {
delete[] allocated[i].data;
}
for (int i = 0; i < toosmall.size(); i++) {
delete[] toosmall[i].data;
}
}
void IntCache::ReleaseThreadStorage() {
ThreadStorage* tls = (ThreadStorage*)TlsGetValue(tlsIdx);
delete tls;
}
intArray IntCache::allocate(int size) {
ThreadStorage* tls = (ThreadStorage*)TlsGetValue(tlsIdx);
if (size <= TINY_CUTOFF) {
if (tls->tcache.empty()) {
intArray result = intArray(TINY_CUTOFF, true);
tls->tallocated.push_back(result);
return result;
} else {
intArray result = tls->tcache.back();
tls->tcache.pop_back();
tls->tallocated.push_back(result);
return result;
}
}
if (size > tls->maxSize) {
// app.DebugPrintf("IntCache: New max size: %d\n" , size);
tls->maxSize = size;
// 4J - added - all the vectors in cache & allocated are smaller than
// maxSize so should be discarded. However, we can't delete them until
// the next releaseAll so copy into another vector until then
tls->toosmall.insert(tls->toosmall.end(), tls->cache.begin(),
tls->cache.end());
tls->toosmall.insert(tls->toosmall.end(), tls->allocated.begin(),
tls->allocated.end());
tls->cache.clear();
tls->allocated.clear();
intArray result = intArray(tls->maxSize, true);
tls->allocated.push_back(result);
return result;
} else {
if (tls->cache.empty()) {
intArray result = intArray(tls->maxSize, true);
tls->allocated.push_back(result);
return result;
} else {
intArray result = tls->cache.back();
tls->cache.pop_back();
tls->allocated.push_back(result);
return result;
}
}
}
void IntCache::releaseAll() {
ThreadStorage* tls = (ThreadStorage*)TlsGetValue(tlsIdx);
// 4J - added - we can now remove the vectors that were deemed as too small
// (see comment in IntCache::allocate)
for (int i = 0; i < tls->toosmall.size(); i++) {
delete[] tls->toosmall[i].data;
}
tls->toosmall.clear();
if (!tls->cache.empty()) {
delete[] tls->cache.back().data;
tls->cache.pop_back();
}
if (!tls->tcache.empty()) {
delete[] tls->tcache.back().data;
tls->tcache.pop_back();
}
tls->cache.insert(tls->cache.end(), tls->allocated.begin(),
tls->allocated.end());
tls->tcache.insert(tls->tcache.end(), tls->tallocated.begin(),
tls->tallocated.end());
tls->allocated.clear();
tls->tallocated.clear();
}
// 4J added so that we can fully reset between levels
void IntCache::Reset() {
ThreadStorage* tls = (ThreadStorage*)TlsGetValue(tlsIdx);
tls->maxSize = TINY_CUTOFF;
for (int i = 0; i < tls->allocated.size(); i++) {
delete[] tls->allocated[i].data;
}
tls->allocated.clear();
for (int i = 0; i < tls->cache.size(); i++) {
delete[] tls->cache[i].data;
}
tls->cache.clear();
for (int i = 0; i < tls->tallocated.size(); i++) {
delete[] tls->tallocated[i].data;
}
tls->tallocated.clear();
for (int i = 0; i < tls->tcache.size(); i++) {
delete[] tls->tcache[i].data;
}
tls->tcache.clear();
for (int i = 0; i < tls->toosmall.size(); i++) {
delete[] tls->toosmall[i].data;
}
tls->toosmall.clear();
}