[Glide64] Clean up GlideHQ/TxCache.cpp

This commit is contained in:
zilmar 2016-02-05 04:28:21 +11:00
parent 612bbb71e5
commit 0ebcf6d608
1 changed files with 289 additions and 289 deletions

View File

@ -33,400 +33,400 @@
TxCache::~TxCache() TxCache::~TxCache()
{ {
/* free memory, clean up, etc */ /* free memory, clean up, etc */
clear(); clear();
delete _txUtil; delete _txUtil;
} }
TxCache::TxCache(int options, int cachesize, const wchar_t *path, const wchar_t *ident, TxCache::TxCache(int options, int cachesize, const wchar_t *path, const wchar_t *ident,
dispInfoFuncExt callback) dispInfoFuncExt callback)
{ {
_txUtil = new TxUtil(); _txUtil = new TxUtil();
_options = options; _options = options;
_cacheSize = cachesize; _cacheSize = cachesize;
_callback = callback; _callback = callback;
_totalSize = 0; _totalSize = 0;
/* save path name */ /* save path name */
if (path) if (path)
_path.assign(path); _path.assign(path);
/* save ROM name */ /* save ROM name */
if (ident) if (ident)
_ident.assign(ident); _ident.assign(ident);
/* zlib memory buffers to (de)compress hires textures */ /* zlib memory buffers to (de)compress hires textures */
if (_options & (GZ_TEXCACHE|GZ_HIRESTEXCACHE)) { if (_options & (GZ_TEXCACHE | GZ_HIRESTEXCACHE)) {
_gzdest0 = TxMemBuf::getInstance()->get(0); _gzdest0 = TxMemBuf::getInstance()->get(0);
_gzdest1 = TxMemBuf::getInstance()->get(1); _gzdest1 = TxMemBuf::getInstance()->get(1);
_gzdestLen = (TxMemBuf::getInstance()->size_of(0) < TxMemBuf::getInstance()->size_of(1)) ? _gzdestLen = (TxMemBuf::getInstance()->size_of(0) < TxMemBuf::getInstance()->size_of(1)) ?
TxMemBuf::getInstance()->size_of(0) : TxMemBuf::getInstance()->size_of(1); TxMemBuf::getInstance()->size_of(0) : TxMemBuf::getInstance()->size_of(1);
if (!_gzdest0 || !_gzdest1 || !_gzdestLen) { if (!_gzdest0 || !_gzdest1 || !_gzdestLen) {
_options &= ~(GZ_TEXCACHE|GZ_HIRESTEXCACHE); _options &= ~(GZ_TEXCACHE | GZ_HIRESTEXCACHE);
_gzdest0 = NULL; _gzdest0 = NULL;
_gzdest1 = NULL; _gzdest1 = NULL;
_gzdestLen = 0; _gzdestLen = 0;
}
} }
}
} }
boolean boolean
TxCache::add(uint64 checksum, GHQTexInfo *info, int dataSize) TxCache::add(uint64 checksum, GHQTexInfo *info, int dataSize)
{ {
/* NOTE: dataSize must be provided if info->data is zlib compressed. */ /* NOTE: dataSize must be provided if info->data is zlib compressed. */
if (!checksum || !info->data) return 0; if (!checksum || !info->data) return 0;
uint8 *dest = info->data; uint8 *dest = info->data;
uint16 format = info->format; uint16 format = info->format;
if (!dataSize) { if (!dataSize) {
dataSize = _txUtil->sizeofTx(info->width, info->height, info->format); dataSize = _txUtil->sizeofTx(info->width, info->height, info->format);
if (!dataSize) return 0; if (!dataSize) return 0;
if (_options & (GZ_TEXCACHE|GZ_HIRESTEXCACHE)) { if (_options & (GZ_TEXCACHE | GZ_HIRESTEXCACHE)) {
/* zlib compress it. compression level:1 (best speed) */ /* zlib compress it. compression level:1 (best speed) */
uLongf destLen = _gzdestLen; uLongf destLen = _gzdestLen;
dest = (dest == _gzdest0) ? _gzdest1 : _gzdest0; dest = (dest == _gzdest0) ? _gzdest1 : _gzdest0;
if (compress2(dest, &destLen, info->data, dataSize, 1) != Z_OK) { if (compress2(dest, &destLen, info->data, dataSize, 1) != Z_OK) {
dest = info->data; dest = info->data;
DBG_INFO(80, L"Error: zlib compression failed!\n"); DBG_INFO(80, L"Error: zlib compression failed!\n");
} else { }
DBG_INFO(80, L"zlib compressed: %.02fkb->%.02fkb\n", (float)dataSize/1000, (float)destLen/1000); else {
dataSize = destLen; DBG_INFO(80, L"zlib compressed: %.02fkb->%.02fkb\n", (float)dataSize / 1000, (float)destLen / 1000);
format |= GR_TEXFMT_GZ; dataSize = destLen;
} format |= GR_TEXFMT_GZ;
} }
}
/* if cache size exceeds limit, remove old cache */
if (_cacheSize > 0) {
_totalSize += dataSize;
if ((_totalSize > _cacheSize) && !_cachelist.empty()) {
/* _cachelist is arranged so that frequently used textures are in the back */
std::list<uint64>::iterator itList = _cachelist.begin();
while (itList != _cachelist.end()) {
/* find it in _cache */
std::map<uint64, TXCACHE*>::iterator itMap = _cache.find(*itList);
if (itMap != _cache.end()) {
/* yep we have it. remove it. */
_totalSize -= (*itMap).second->size;
free((*itMap).second->info.data);
delete (*itMap).second;
_cache.erase(itMap);
} }
itList++;
/* check if memory cache has enough space */
if (_totalSize <= _cacheSize)
break;
}
/* remove from _cachelist */
_cachelist.erase(_cachelist.begin(), itList);
DBG_INFO(80, L"+++++++++\n");
} }
_totalSize -= dataSize;
}
/* cache it */ /* if cache size exceeds limit, remove old cache */
uint8 *tmpdata = (uint8*)malloc(dataSize); if (_cacheSize > 0) {
if (tmpdata) { _totalSize += dataSize;
TXCACHE *txCache = new TXCACHE; if ((_totalSize > _cacheSize) && !_cachelist.empty()) {
if (txCache) { /* _cachelist is arranged so that frequently used textures are in the back */
/* we can directly write as we filter, but for now we get away std::list<uint64>::iterator itList = _cachelist.begin();
* with doing memcpy after all the filtering is done. while (itList != _cachelist.end()) {
*/ /* find it in _cache */
memcpy(tmpdata, dest, dataSize); std::map<uint64, TXCACHE*>::iterator itMap = _cache.find(*itList);
if (itMap != _cache.end()) {
/* yep we have it. remove it. */
_totalSize -= (*itMap).second->size;
free((*itMap).second->info.data);
delete (*itMap).second;
_cache.erase(itMap);
}
itList++;
/* copy it */ /* check if memory cache has enough space */
memcpy(&txCache->info, info, sizeof(GHQTexInfo)); if (_totalSize <= _cacheSize)
txCache->info.data = tmpdata; break;
txCache->info.format = format; }
txCache->size = dataSize; /* remove from _cachelist */
_cachelist.erase(_cachelist.begin(), itList);
/* add to cache */ DBG_INFO(80, L"+++++++++\n");
if (_cacheSize > 0) { }
_cachelist.push_back(checksum); _totalSize -= dataSize;
txCache->it = --(_cachelist.end()); }
}
/* _cache[checksum] = txCache; */ /* cache it */
_cache.insert(std::map<uint64, TXCACHE*>::value_type(checksum, txCache)); uint8 *tmpdata = (uint8*)malloc(dataSize);
if (tmpdata) {
TXCACHE *txCache = new TXCACHE;
if (txCache) {
/* we can directly write as we filter, but for now we get away
* with doing memcpy after all the filtering is done.
*/
memcpy(tmpdata, dest, dataSize);
/* copy it */
memcpy(&txCache->info, info, sizeof(GHQTexInfo));
txCache->info.data = tmpdata;
txCache->info.format = format;
txCache->size = dataSize;
/* add to cache */
if (_cacheSize > 0) {
_cachelist.push_back(checksum);
txCache->it = --(_cachelist.end());
}
/* _cache[checksum] = txCache; */
_cache.insert(std::map<uint64, TXCACHE*>::value_type(checksum, txCache));
#ifdef DEBUG #ifdef DEBUG
DBG_INFO(80, L"[%5d] added!! crc:%08X %08X %d x %d gfmt:%x total:%.02fmb\n", DBG_INFO(80, L"[%5d] added!! crc:%08X %08X %d x %d gfmt:%x total:%.02fmb\n",
_cache.size(), (uint32)(checksum >> 32), (uint32)(checksum & 0xffffffff), _cache.size(), (uint32)(checksum >> 32), (uint32)(checksum & 0xffffffff),
info->width, info->height, info->format, (float)_totalSize/1000000); info->width, info->height, info->format, (float)_totalSize/1000000);
DBG_INFO(80, L"smalllodlog2:%d largelodlog2:%d aspectratiolog2:%d\n", DBG_INFO(80, L"smalllodlog2:%d largelodlog2:%d aspectratiolog2:%d\n",
txCache->info.smallLodLog2, txCache->info.largeLodLog2, txCache->info.aspectRatioLog2); txCache->info.smallLodLog2, txCache->info.largeLodLog2, txCache->info.aspectRatioLog2);
if (info->tiles) { if (info->tiles) {
DBG_INFO(80, L"tiles:%d un-tiled size:%d x %d\n", info->tiles, info->untiled_width, info->untiled_height); DBG_INFO(80, L"tiles:%d un-tiled size:%d x %d\n", info->tiles, info->untiled_width, info->untiled_height);
} }
if (_cacheSize > 0) { if (_cacheSize > 0) {
DBG_INFO(80, L"cache max config:%.02fmb\n", (float)_cacheSize/1000000); DBG_INFO(80, L"cache max config:%.02fmb\n", (float)_cacheSize/1000000);
if (_cache.size() != _cachelist.size()) { if (_cache.size() != _cachelist.size()) {
DBG_INFO(80, L"Error: cache/cachelist mismatch! (%d/%d)\n", _cache.size(), _cachelist.size()); DBG_INFO(80, L"Error: cache/cachelist mismatch! (%d/%d)\n", _cache.size(), _cachelist.size());
}
} }
}
#endif #endif
/* total cache size */ /* total cache size */
_totalSize += dataSize; _totalSize += dataSize;
return 1; return 1;
} }
free(tmpdata); free(tmpdata);
} }
return 0; return 0;
} }
boolean boolean
TxCache::get(uint64 checksum, GHQTexInfo *info) TxCache::get(uint64 checksum, GHQTexInfo *info)
{ {
if (!checksum || _cache.empty()) return 0; if (!checksum || _cache.empty()) return 0;
/* find a match in cache */ /* find a match in cache */
std::map<uint64, TXCACHE*>::iterator itMap = _cache.find(checksum); std::map<uint64, TXCACHE*>::iterator itMap = _cache.find(checksum);
if (itMap != _cache.end()) { if (itMap != _cache.end()) {
/* yep, we've got it. */ /* yep, we've got it. */
memcpy(info, &(((*itMap).second)->info), sizeof(GHQTexInfo)); memcpy(info, &(((*itMap).second)->info), sizeof(GHQTexInfo));
/* push it to the back of the list */ /* push it to the back of the list */
if (_cacheSize > 0) { if (_cacheSize > 0) {
_cachelist.erase(((*itMap).second)->it); _cachelist.erase(((*itMap).second)->it);
_cachelist.push_back(checksum); _cachelist.push_back(checksum);
((*itMap).second)->it = --(_cachelist.end()); ((*itMap).second)->it = --(_cachelist.end());
}
/* zlib decompress it */
if (info->format & GR_TEXFMT_GZ) {
uLongf destLen = _gzdestLen;
uint8 *dest = (_gzdest0 == info->data) ? _gzdest1 : _gzdest0;
if (uncompress(dest, &destLen, info->data, ((*itMap).second)->size) != Z_OK) {
DBG_INFO(80, L"Error: zlib decompression failed!\n");
return 0;
}
info->data = dest;
info->format &= ~GR_TEXFMT_GZ;
DBG_INFO(80, L"zlib decompressed: %.02fkb->%.02fkb\n", (float)(((*itMap).second)->size) / 1000, (float)destLen / 1000);
}
return 1;
} }
/* zlib decompress it */ return 0;
if (info->format & GR_TEXFMT_GZ) {
uLongf destLen = _gzdestLen;
uint8 *dest = (_gzdest0 == info->data) ? _gzdest1 : _gzdest0;
if (uncompress(dest, &destLen, info->data, ((*itMap).second)->size) != Z_OK) {
DBG_INFO(80, L"Error: zlib decompression failed!\n");
return 0;
}
info->data = dest;
info->format &= ~GR_TEXFMT_GZ;
DBG_INFO(80, L"zlib decompressed: %.02fkb->%.02fkb\n", (float)(((*itMap).second)->size)/1000, (float)destLen/1000);
}
return 1;
}
return 0;
} }
boolean boolean
TxCache::save(const wchar_t *path, const wchar_t *filename, int config) TxCache::save(const wchar_t *path, const wchar_t *filename, int config)
{ {
if (!_cache.empty()) { if (!_cache.empty()) {
/* dump cache to disk */ /* dump cache to disk */
char cbuf[MAX_PATH]; char cbuf[MAX_PATH];
CPath cachepath(stdstr().FromUTF16(path),""); CPath cachepath(stdstr().FromUTF16(path), "");
cachepath.DirectoryCreate(); cachepath.DirectoryCreate();
/* Ugly hack to enable fopen/gzopen in Win9x */ /* Ugly hack to enable fopen/gzopen in Win9x */
#ifdef _WIN32 #ifdef _WIN32
wchar_t curpath[MAX_PATH]; wchar_t curpath[MAX_PATH];
GETCWD(MAX_PATH, curpath); GETCWD(MAX_PATH, curpath);
cachepath.ChangeDirectory(); cachepath.ChangeDirectory();
#else #else
char curpath[MAX_PATH]; char curpath[MAX_PATH];
wcstombs(cbuf, cachepath.wstring().c_str(), MAX_PATH); wcstombs(cbuf, cachepath.wstring().c_str(), MAX_PATH);
GETCWD(MAX_PATH, curpath); GETCWD(MAX_PATH, curpath);
CHDIR(cbuf); CHDIR(cbuf);
#endif #endif
wcstombs(cbuf, filename, MAX_PATH); wcstombs(cbuf, filename, MAX_PATH);
gzFile gzfp = gzopen(cbuf, "wb1"); gzFile gzfp = gzopen(cbuf, "wb1");
DBG_INFO(80, L"gzfp:%x file:%ls\n", gzfp, filename); DBG_INFO(80, L"gzfp:%x file:%ls\n", gzfp, filename);
if (gzfp) { if (gzfp) {
/* write header to determine config match */ /* write header to determine config match */
gzwrite(gzfp, &config, 4); gzwrite(gzfp, &config, 4);
std::map<uint64, TXCACHE*>::iterator itMap = _cache.begin(); std::map<uint64, TXCACHE*>::iterator itMap = _cache.begin();
while (itMap != _cache.end()) { while (itMap != _cache.end()) {
uint8 *dest = (*itMap).second->info.data; uint8 *dest = (*itMap).second->info.data;
uint32 destLen = (*itMap).second->size; uint32 destLen = (*itMap).second->size;
uint16 format = (*itMap).second->info.format; uint16 format = (*itMap).second->info.format;
/* to keep things simple, we save the texture data in a zlib uncompressed state. */ /* to keep things simple, we save the texture data in a zlib uncompressed state. */
/* sigh... for those who cannot wait the extra few seconds. changed to keep /* sigh... for those who cannot wait the extra few seconds. changed to keep
* texture data in a zlib compressed state. if the GZ_TEXCACHE or GZ_HIRESTEXCACHE * texture data in a zlib compressed state. if the GZ_TEXCACHE or GZ_HIRESTEXCACHE
* option is toggled, the cache will need to be rebuilt. * option is toggled, the cache will need to be rebuilt.
*/ */
/*if (format & GR_TEXFMT_GZ) { /*if (format & GR_TEXFMT_GZ) {
dest = _gzdest0; dest = _gzdest0;
destLen = _gzdestLen; destLen = _gzdestLen;
if (dest && destLen) { if (dest && destLen) {
if (uncompress(dest, &destLen, (*itMap).second->info.data, (*itMap).second->size) != Z_OK) { if (uncompress(dest, &destLen, (*itMap).second->info.data, (*itMap).second->size) != Z_OK) {
dest = NULL; dest = NULL;
destLen = 0; destLen = 0;
}
format &= ~GR_TEXFMT_GZ;
}
}*/
if (dest && destLen) {
/* texture checksum */
gzwrite(gzfp, &((*itMap).first), 8);
/* other texture info */
gzwrite(gzfp, &((*itMap).second->info.width), 4);
gzwrite(gzfp, &((*itMap).second->info.height), 4);
gzwrite(gzfp, &format, 2);
gzwrite(gzfp, &((*itMap).second->info.smallLodLog2), 4);
gzwrite(gzfp, &((*itMap).second->info.largeLodLog2), 4);
gzwrite(gzfp, &((*itMap).second->info.aspectRatioLog2), 4);
gzwrite(gzfp, &((*itMap).second->info.tiles), 4);
gzwrite(gzfp, &((*itMap).second->info.untiled_width), 4);
gzwrite(gzfp, &((*itMap).second->info.untiled_height), 4);
gzwrite(gzfp, &((*itMap).second->info.is_hires_tex), 1);
gzwrite(gzfp, &destLen, 4);
gzwrite(gzfp, dest, destLen);
}
itMap++;
/* not ready yet */
/*if (_callback)
(*_callback)(L"Total textures saved to HDD: %d\n", std::distance(itMap, _cache.begin()));*/
} }
format &= ~GR_TEXFMT_GZ; gzclose(gzfp);
}
}*/
if (dest && destLen) {
/* texture checksum */
gzwrite(gzfp, &((*itMap).first), 8);
/* other texture info */
gzwrite(gzfp, &((*itMap).second->info.width), 4);
gzwrite(gzfp, &((*itMap).second->info.height), 4);
gzwrite(gzfp, &format, 2);
gzwrite(gzfp, &((*itMap).second->info.smallLodLog2), 4);
gzwrite(gzfp, &((*itMap).second->info.largeLodLog2), 4);
gzwrite(gzfp, &((*itMap).second->info.aspectRatioLog2), 4);
gzwrite(gzfp, &((*itMap).second->info.tiles), 4);
gzwrite(gzfp, &((*itMap).second->info.untiled_width), 4);
gzwrite(gzfp, &((*itMap).second->info.untiled_height), 4);
gzwrite(gzfp, &((*itMap).second->info.is_hires_tex), 1);
gzwrite(gzfp, &destLen, 4);
gzwrite(gzfp, dest, destLen);
} }
itMap++; CHDIR(curpath);
/* not ready yet */
/*if (_callback)
(*_callback)(L"Total textures saved to HDD: %d\n", std::distance(itMap, _cache.begin()));*/
}
gzclose(gzfp);
} }
return _cache.empty();
CHDIR(curpath);
}
return _cache.empty();
} }
boolean boolean
TxCache::load(const wchar_t *path, const wchar_t *filename, int config) TxCache::load(const wchar_t *path, const wchar_t *filename, int config)
{ {
/* find it on disk */ /* find it on disk */
CPath cbuf(stdstr().FromUTF16(path).c_str(),stdstr().FromUTF16(filename).c_str()); CPath cbuf(stdstr().FromUTF16(path).c_str(), stdstr().FromUTF16(filename).c_str());
gzFile gzfp = gzopen(cbuf, "rb"); gzFile gzfp = gzopen(cbuf, "rb");
DBG_INFO(80, L"gzfp:%x file:%ls\n", gzfp, filename); DBG_INFO(80, L"gzfp:%x file:%ls\n", gzfp, filename);
if (gzfp) { if (gzfp) {
/* yep, we have it. load it into memory cache. */ /* yep, we have it. load it into memory cache. */
int dataSize; int dataSize;
uint64 checksum; uint64 checksum;
GHQTexInfo tmpInfo; GHQTexInfo tmpInfo;
int tmpconfig; int tmpconfig;
/* read header to determine config match */ /* read header to determine config match */
gzread(gzfp, &tmpconfig, 4); gzread(gzfp, &tmpconfig, 4);
if (tmpconfig == config) { if (tmpconfig == config) {
do { do {
memset(&tmpInfo, 0, sizeof(GHQTexInfo)); memset(&tmpInfo, 0, sizeof(GHQTexInfo));
gzread(gzfp, &checksum, 8); gzread(gzfp, &checksum, 8);
gzread(gzfp, &tmpInfo.width, 4); gzread(gzfp, &tmpInfo.width, 4);
gzread(gzfp, &tmpInfo.height, 4); gzread(gzfp, &tmpInfo.height, 4);
gzread(gzfp, &tmpInfo.format, 2); gzread(gzfp, &tmpInfo.format, 2);
gzread(gzfp, &tmpInfo.smallLodLog2, 4); gzread(gzfp, &tmpInfo.smallLodLog2, 4);
gzread(gzfp, &tmpInfo.largeLodLog2, 4); gzread(gzfp, &tmpInfo.largeLodLog2, 4);
gzread(gzfp, &tmpInfo.aspectRatioLog2, 4); gzread(gzfp, &tmpInfo.aspectRatioLog2, 4);
gzread(gzfp, &tmpInfo.tiles, 4); gzread(gzfp, &tmpInfo.tiles, 4);
gzread(gzfp, &tmpInfo.untiled_width, 4); gzread(gzfp, &tmpInfo.untiled_width, 4);
gzread(gzfp, &tmpInfo.untiled_height, 4); gzread(gzfp, &tmpInfo.untiled_height, 4);
gzread(gzfp, &tmpInfo.is_hires_tex, 1); gzread(gzfp, &tmpInfo.is_hires_tex, 1);
gzread(gzfp, &dataSize, 4); gzread(gzfp, &dataSize, 4);
tmpInfo.data = (uint8*)malloc(dataSize); tmpInfo.data = (uint8*)malloc(dataSize);
if (tmpInfo.data) { if (tmpInfo.data) {
gzread(gzfp, tmpInfo.data, dataSize); gzread(gzfp, tmpInfo.data, dataSize);
/* add to memory cache */ /* add to memory cache */
add(checksum, &tmpInfo, (tmpInfo.format & GR_TEXFMT_GZ) ? dataSize : 0); add(checksum, &tmpInfo, (tmpInfo.format & GR_TEXFMT_GZ) ? dataSize : 0);
free(tmpInfo.data); free(tmpInfo.data);
} else { }
gzseek(gzfp, dataSize, SEEK_CUR); else {
gzseek(gzfp, dataSize, SEEK_CUR);
}
/* skip in between to prevent the loop from being tied down to vsync */
if (_callback && (!(_cache.size() % 100) || gzeof(gzfp)))
(*_callback)(L"[%d] total mem:%.02fmb - %ls\n", _cache.size(), (float)_totalSize / 1000000, filename);
} while (!gzeof(gzfp));
gzclose(gzfp);
} }
/* skip in between to prevent the loop from being tied down to vsync */
if (_callback && (!(_cache.size() % 100) || gzeof(gzfp)))
(*_callback)(L"[%d] total mem:%.02fmb - %ls\n", _cache.size(), (float)_totalSize/1000000, filename);
} while (!gzeof(gzfp));
gzclose(gzfp);
} }
}
return !_cache.empty(); return !_cache.empty();
} }
boolean boolean
TxCache::del(uint64 checksum) TxCache::del(uint64 checksum)
{ {
if (!checksum || _cache.empty()) return 0; if (!checksum || _cache.empty()) return 0;
std::map<uint64, TXCACHE*>::iterator itMap = _cache.find(checksum); std::map<uint64, TXCACHE*>::iterator itMap = _cache.find(checksum);
if (itMap != _cache.end()) { if (itMap != _cache.end()) {
/* for texture cache (not hi-res cache) */
if (!_cachelist.empty()) _cachelist.erase(((*itMap).second)->it);
/* for texture cache (not hi-res cache) */ /* remove from cache */
if (!_cachelist.empty()) _cachelist.erase(((*itMap).second)->it); free((*itMap).second->info.data);
_totalSize -= (*itMap).second->size;
delete (*itMap).second;
_cache.erase(itMap);
/* remove from cache */ DBG_INFO(80, L"removed from cache: checksum = %08X %08X\n", (uint32)(checksum & 0xffffffff), (uint32)(checksum >> 32));
free((*itMap).second->info.data);
_totalSize -= (*itMap).second->size;
delete (*itMap).second;
_cache.erase(itMap);
DBG_INFO(80, L"removed from cache: checksum = %08X %08X\n", (uint32)(checksum & 0xffffffff), (uint32)(checksum >> 32)); return 1;
}
return 1; return 0;
}
return 0;
} }
boolean boolean
TxCache::is_cached(uint64 checksum) TxCache::is_cached(uint64 checksum)
{ {
std::map<uint64, TXCACHE*>::iterator itMap = _cache.find(checksum); std::map<uint64, TXCACHE*>::iterator itMap = _cache.find(checksum);
if (itMap != _cache.end()) return 1; if (itMap != _cache.end()) return 1;
return 0; return 0;
} }
void void
TxCache::clear() TxCache::clear()
{ {
if (!_cache.empty()) { if (!_cache.empty()) {
std::map<uint64, TXCACHE*>::iterator itMap = _cache.begin(); std::map<uint64, TXCACHE*>::iterator itMap = _cache.begin();
while (itMap != _cache.end()) { while (itMap != _cache.end()) {
free((*itMap).second->info.data); free((*itMap).second->info.data);
delete (*itMap).second; delete (*itMap).second;
itMap++; itMap++;
}
_cache.clear();
} }
_cache.clear();
}
if (!_cachelist.empty()) _cachelist.clear(); if (!_cachelist.empty()) _cachelist.clear();
_totalSize = 0; _totalSize = 0;
} }