mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 10:54:24 -04:00
separate out CacheKey and CacheEntry
This commit is contained in:
parent
b407c2929b
commit
f410cff0cd
@ -373,26 +373,36 @@ set_result(const Geom *geom_result, const GeomVertexData *data_result) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: Geom::CacheEntry::Constructor
|
// Function: Geom::CacheKey::Constructor
|
||||||
// Access: Public
|
// Access: Public
|
||||||
// Description: This constructor makes an invalid CacheEntry that
|
// Description:
|
||||||
// holds no data. CacheEntries like this are normally
|
|
||||||
// not stored in the cache; this is usually used as a
|
|
||||||
// key to find an existing (valid) CacheEntry already in
|
|
||||||
// the cache.
|
|
||||||
//
|
|
||||||
// However, it is possible for an empty CacheEntry to
|
|
||||||
// end up in the cache if its data gets cleared by
|
|
||||||
// clear_cache_stage().
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE Geom::CacheEntry::
|
INLINE Geom::CacheKey::
|
||||||
CacheEntry(const GeomVertexData *source_data, const GeomMunger *modifier) :
|
CacheKey(const GeomVertexData *source_data, const GeomMunger *modifier) :
|
||||||
_source(NULL),
|
|
||||||
_source_data(source_data),
|
_source_data(source_data),
|
||||||
_modifier(modifier)
|
_modifier(modifier)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: Geom::CacheKey::operator <
|
||||||
|
// Access: Public
|
||||||
|
// Description: Provides a unique ordering within the map.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE bool Geom::CacheKey::
|
||||||
|
operator < (const CacheKey &other) const {
|
||||||
|
if (_modifier != other._modifier) {
|
||||||
|
int compare = _modifier->geom_compare_to(*other._modifier);
|
||||||
|
if (compare != 0) {
|
||||||
|
return (compare < 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (_source_data != other._source_data) {
|
||||||
|
return (_source_data < other._source_data);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: Geom::CacheEntry::Constructor
|
// Function: Geom::CacheEntry::Constructor
|
||||||
// Access: Public
|
// Access: Public
|
||||||
@ -402,30 +412,10 @@ INLINE Geom::CacheEntry::
|
|||||||
CacheEntry(Geom *source, const GeomVertexData *source_data,
|
CacheEntry(Geom *source, const GeomVertexData *source_data,
|
||||||
const GeomMunger *modifier) :
|
const GeomMunger *modifier) :
|
||||||
_source(source),
|
_source(source),
|
||||||
_source_data(source_data),
|
_key(source_data, modifier)
|
||||||
_modifier(modifier)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: Geom::CacheEntry::operator <
|
|
||||||
// Access: Public
|
|
||||||
// Description: Provides a unique ordering within the set.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
INLINE bool Geom::CacheEntry::
|
|
||||||
operator < (const CacheEntry &other) const {
|
|
||||||
if (_modifier != other._modifier) {
|
|
||||||
int compare = _modifier->geom_compare_to(*other._modifier);
|
|
||||||
if (compare != 0) {
|
|
||||||
return (compare < 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (_source_data != other._source_data) {
|
|
||||||
return (_source_data < other._source_data);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: Geom::CData::Constructor
|
// Function: Geom::CData::Constructor
|
||||||
|
@ -806,7 +806,7 @@ clear_cache() {
|
|||||||
for (Cache::iterator ci = _cache.begin();
|
for (Cache::iterator ci = _cache.begin();
|
||||||
ci != _cache.end();
|
ci != _cache.end();
|
||||||
++ci) {
|
++ci) {
|
||||||
CacheEntry *entry = (*ci);
|
CacheEntry *entry = (*ci).second;
|
||||||
entry->erase();
|
entry->erase();
|
||||||
}
|
}
|
||||||
_cache.clear();
|
_cache.clear();
|
||||||
@ -829,7 +829,7 @@ clear_cache_stage(Thread *current_thread) {
|
|||||||
for (Cache::iterator ci = _cache.begin();
|
for (Cache::iterator ci = _cache.begin();
|
||||||
ci != _cache.end();
|
ci != _cache.end();
|
||||||
++ci) {
|
++ci) {
|
||||||
CacheEntry *entry = (*ci);
|
CacheEntry *entry = (*ci).second;
|
||||||
CDCacheWriter cdata(entry->_cycler, current_thread);
|
CDCacheWriter cdata(entry->_cycler, current_thread);
|
||||||
cdata->set_result(NULL, NULL);
|
cdata->set_result(NULL, NULL);
|
||||||
}
|
}
|
||||||
@ -1244,9 +1244,9 @@ make_copy() const {
|
|||||||
void Geom::CacheEntry::
|
void Geom::CacheEntry::
|
||||||
evict_callback() {
|
evict_callback() {
|
||||||
MutexHolder holder(_source->_cache_lock);
|
MutexHolder holder(_source->_cache_lock);
|
||||||
Cache::iterator ci = _source->_cache.find(this);
|
Cache::iterator ci = _source->_cache.find(&_key);
|
||||||
nassertv(ci != _source->_cache.end());
|
nassertv(ci != _source->_cache.end());
|
||||||
nassertv((*ci) == this);
|
nassertv((*ci).second == this);
|
||||||
_source->_cache.erase(ci);
|
_source->_cache.erase(ci);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1258,7 +1258,7 @@ evict_callback() {
|
|||||||
void Geom::CacheEntry::
|
void Geom::CacheEntry::
|
||||||
output(ostream &out) const {
|
output(ostream &out) const {
|
||||||
out << "geom " << (void *)_source << ", "
|
out << "geom " << (void *)_source << ", "
|
||||||
<< (const void *)_modifier;
|
<< (const void *)_key._modifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
#include "pointerTo.h"
|
#include "pointerTo.h"
|
||||||
#include "indirectLess.h"
|
#include "indirectLess.h"
|
||||||
#include "pset.h"
|
#include "pset.h"
|
||||||
|
#include "pmap.h"
|
||||||
#include "boundingVolume.h"
|
#include "boundingVolume.h"
|
||||||
#include "pStatCollector.h"
|
#include "pStatCollector.h"
|
||||||
#include "deletedChain.h"
|
#include "deletedChain.h"
|
||||||
@ -197,27 +198,38 @@ private:
|
|||||||
typedef CycleDataReader<CDataCache> CDCacheReader;
|
typedef CycleDataReader<CDataCache> CDCacheReader;
|
||||||
typedef CycleDataWriter<CDataCache> CDCacheWriter;
|
typedef CycleDataWriter<CDataCache> CDCacheWriter;
|
||||||
|
|
||||||
public: // It is not clear why MSVC7 needs this class to be public.
|
public:
|
||||||
|
// The CacheKey class separates out just the part of CacheEntry that
|
||||||
|
// is used to key the cache entry within the map. We have this as a
|
||||||
|
// separate class so we can easily look up a new entry in the map,
|
||||||
|
// without having to execute the relatively expensive CacheEntry
|
||||||
|
// constructor.
|
||||||
|
class CacheKey {
|
||||||
|
public:
|
||||||
|
INLINE CacheKey(const GeomVertexData *source_data,
|
||||||
|
const GeomMunger *modifier);
|
||||||
|
INLINE bool operator < (const CacheKey &other) const;
|
||||||
|
|
||||||
|
CPT(GeomVertexData) _source_data;
|
||||||
|
CPT(GeomMunger) _modifier;
|
||||||
|
};
|
||||||
|
// It is not clear why MSVC7 needs this class to be public.
|
||||||
class CacheEntry : public GeomCacheEntry {
|
class CacheEntry : public GeomCacheEntry {
|
||||||
public:
|
public:
|
||||||
INLINE CacheEntry(const GeomVertexData *source_data,
|
|
||||||
const GeomMunger *modifier);
|
|
||||||
INLINE CacheEntry(Geom *source,
|
INLINE CacheEntry(Geom *source,
|
||||||
const GeomVertexData *source_data,
|
const GeomVertexData *source_data,
|
||||||
const GeomMunger *modifier);
|
const GeomMunger *modifier);
|
||||||
INLINE bool operator < (const CacheEntry &other) const;
|
|
||||||
ALLOC_DELETED_CHAIN(CacheEntry);
|
ALLOC_DELETED_CHAIN(CacheEntry);
|
||||||
|
|
||||||
virtual void evict_callback();
|
virtual void evict_callback();
|
||||||
virtual void output(ostream &out) const;
|
virtual void output(ostream &out) const;
|
||||||
|
|
||||||
Geom *_source; // A back pointer to the containing Geom
|
Geom *_source; // A back pointer to the containing Geom
|
||||||
CPT(GeomVertexData) _source_data;
|
CacheKey _key;
|
||||||
CPT(GeomMunger) _modifier;
|
|
||||||
|
|
||||||
PipelineCycler<CDataCache> _cycler;
|
PipelineCycler<CDataCache> _cycler;
|
||||||
};
|
};
|
||||||
typedef pset<PT(CacheEntry), IndirectLess<CacheEntry> > Cache;
|
typedef pmap<const CacheKey *, PT(CacheEntry), IndirectLess<CacheKey> > Cache;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// This is the data that must be cycled between pipeline stages.
|
// This is the data that must be cycled between pipeline stages.
|
||||||
|
@ -115,15 +115,14 @@ munge_geom(CPT(Geom) &geom, CPT(GeomVertexData) &data,
|
|||||||
// applied it.
|
// applied it.
|
||||||
PT(Geom::CacheEntry) entry;
|
PT(Geom::CacheEntry) entry;
|
||||||
|
|
||||||
Geom::CacheEntry temp_entry(source_data, this);
|
Geom::CacheKey key(source_data, this);
|
||||||
temp_entry.local_object();
|
|
||||||
|
|
||||||
geom->_cache_lock.lock();
|
geom->_cache_lock.lock();
|
||||||
Geom::Cache::const_iterator ci = geom->_cache.find(&temp_entry);
|
Geom::Cache::const_iterator ci = geom->_cache.find(&key);
|
||||||
if (ci == geom->_cache.end()) {
|
if (ci == geom->_cache.end()) {
|
||||||
geom->_cache_lock.release();
|
geom->_cache_lock.release();
|
||||||
} else {
|
} else {
|
||||||
entry = (*ci);
|
entry = (*ci).second;
|
||||||
geom->_cache_lock.release();
|
geom->_cache_lock.release();
|
||||||
nassertv(entry->_source == geom);
|
nassertv(entry->_source == geom);
|
||||||
|
|
||||||
@ -164,7 +163,7 @@ munge_geom(CPT(Geom) &geom, CPT(GeomVertexData) &data,
|
|||||||
entry = new Geom::CacheEntry(orig_geom, source_data, this);
|
entry = new Geom::CacheEntry(orig_geom, source_data, this);
|
||||||
{
|
{
|
||||||
MutexHolder holder(orig_geom->_cache_lock);
|
MutexHolder holder(orig_geom->_cache_lock);
|
||||||
bool inserted = orig_geom->_cache.insert(entry).second;
|
bool inserted = orig_geom->_cache.insert(Geom::Cache::value_type(&entry->_key, entry)).second;
|
||||||
if (!inserted) {
|
if (!inserted) {
|
||||||
// Some other thread must have beat us to the punch. Never
|
// Some other thread must have beat us to the punch. Never
|
||||||
// mind.
|
// mind.
|
||||||
|
@ -403,48 +403,38 @@ CDataCache(const GeomVertexData::CDataCache ©) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: GeomVertexData::CacheEntry::Constructor
|
// Function: GeomVertexData::CacheKey::Constructor
|
||||||
// Access: Public
|
// Access: Public
|
||||||
// Description: This constructor makes an invalid CacheEntry that
|
// Description:
|
||||||
// holds no data. CacheEntries like this are normally
|
|
||||||
// not stored in the cache; this is usually used as a
|
|
||||||
// key to find an existing (valid) CacheEntry already in
|
|
||||||
// the cache.
|
|
||||||
//
|
|
||||||
// However, it is possible for an empty CacheEntry to
|
|
||||||
// end up in the cache if its data gets cleared by
|
|
||||||
// clear_cache_stage().
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE GeomVertexData::CacheEntry::
|
INLINE GeomVertexData::CacheKey::
|
||||||
CacheEntry(const GeomVertexFormat *modifier) :
|
CacheKey(const GeomVertexFormat *modifier) :
|
||||||
_source(NULL),
|
|
||||||
_modifier(modifier)
|
_modifier(modifier)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: GeomVertexData::CacheKey::operator <
|
||||||
|
// Access: Public
|
||||||
|
// Description: Provides a unique ordering within the set.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE bool GeomVertexData::CacheKey::
|
||||||
|
operator < (const CacheKey &other) const {
|
||||||
|
return _modifier < other._modifier;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: GeomVertexData::CacheEntry::Constructor
|
// Function: GeomVertexData::CacheEntry::Constructor
|
||||||
// Access: Public
|
// Access: Public
|
||||||
// Description:
|
// Description:
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE GeomVertexData::CacheEntry::
|
INLINE GeomVertexData::CacheEntry::
|
||||||
CacheEntry(GeomVertexData *source,
|
CacheEntry(GeomVertexData *source, const GeomVertexFormat *modifier) :
|
||||||
const GeomVertexFormat *modifier) :
|
|
||||||
_source(source),
|
_source(source),
|
||||||
_modifier(modifier)
|
_key(modifier)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: GeomVertexData::CacheEntry::operator <
|
|
||||||
// Access: Public
|
|
||||||
// Description: Provides a unique ordering within the set.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
INLINE bool GeomVertexData::CacheEntry::
|
|
||||||
operator < (const CacheEntry &other) const {
|
|
||||||
return _modifier < other._modifier;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: GeomVertexData::CData::Constructor
|
// Function: GeomVertexData::CData::Constructor
|
||||||
// Access: Public
|
// Access: Public
|
||||||
|
@ -675,16 +675,15 @@ convert_to(const GeomVertexFormat *new_format) const {
|
|||||||
// it.
|
// it.
|
||||||
PT(CacheEntry) entry;
|
PT(CacheEntry) entry;
|
||||||
|
|
||||||
CacheEntry temp_entry(new_format);
|
CacheKey key(new_format);
|
||||||
temp_entry.local_object();
|
|
||||||
|
|
||||||
_cache_lock.lock();
|
_cache_lock.lock();
|
||||||
Cache::const_iterator ci = _cache.find(&temp_entry);
|
Cache::const_iterator ci = _cache.find(&key);
|
||||||
if (ci == _cache.end()) {
|
if (ci == _cache.end()) {
|
||||||
_cache_lock.release();
|
_cache_lock.release();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
entry = (*ci);
|
entry = (*ci).second;
|
||||||
_cache_lock.release();
|
_cache_lock.release();
|
||||||
nassertr(entry->_source == this, NULL);
|
nassertr(entry->_source == this, NULL);
|
||||||
|
|
||||||
@ -725,7 +724,7 @@ convert_to(const GeomVertexFormat *new_format) const {
|
|||||||
entry = new CacheEntry((GeomVertexData *)this, new_format);
|
entry = new CacheEntry((GeomVertexData *)this, new_format);
|
||||||
{
|
{
|
||||||
MutexHolder holder(_cache_lock);
|
MutexHolder holder(_cache_lock);
|
||||||
bool inserted = ((GeomVertexData *)this)->_cache.insert(entry).second;
|
bool inserted = ((GeomVertexData *)this)->_cache.insert(Cache::value_type(&entry->_key, entry)).second;
|
||||||
if (!inserted) {
|
if (!inserted) {
|
||||||
// Some other thread must have beat us to the punch. Never
|
// Some other thread must have beat us to the punch. Never
|
||||||
// mind.
|
// mind.
|
||||||
@ -1112,7 +1111,7 @@ clear_cache() {
|
|||||||
for (Cache::iterator ci = _cache.begin();
|
for (Cache::iterator ci = _cache.begin();
|
||||||
ci != _cache.end();
|
ci != _cache.end();
|
||||||
++ci) {
|
++ci) {
|
||||||
CacheEntry *entry = (*ci);
|
CacheEntry *entry = (*ci).second;
|
||||||
entry->erase();
|
entry->erase();
|
||||||
}
|
}
|
||||||
_cache.clear();
|
_cache.clear();
|
||||||
@ -1135,7 +1134,7 @@ clear_cache_stage() {
|
|||||||
for (Cache::iterator ci = _cache.begin();
|
for (Cache::iterator ci = _cache.begin();
|
||||||
ci != _cache.end();
|
ci != _cache.end();
|
||||||
++ci) {
|
++ci) {
|
||||||
CacheEntry *entry = (*ci);
|
CacheEntry *entry = (*ci).second;
|
||||||
CDCacheWriter cdata(entry->_cycler);
|
CDCacheWriter cdata(entry->_cycler);
|
||||||
cdata->_result = NULL;
|
cdata->_result = NULL;
|
||||||
}
|
}
|
||||||
@ -1487,9 +1486,9 @@ make_copy() const {
|
|||||||
void GeomVertexData::CacheEntry::
|
void GeomVertexData::CacheEntry::
|
||||||
evict_callback() {
|
evict_callback() {
|
||||||
MutexHolder holder(_source->_cache_lock);
|
MutexHolder holder(_source->_cache_lock);
|
||||||
Cache::iterator ci = _source->_cache.find(this);
|
Cache::iterator ci = _source->_cache.find(&_key);
|
||||||
nassertv(ci != _source->_cache.end());
|
nassertv(ci != _source->_cache.end());
|
||||||
nassertv((*ci) == this);
|
nassertv((*ci).second == this);
|
||||||
_source->_cache.erase(ci);
|
_source->_cache.erase(ci);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1501,7 +1500,7 @@ evict_callback() {
|
|||||||
void GeomVertexData::CacheEntry::
|
void GeomVertexData::CacheEntry::
|
||||||
output(ostream &out) const {
|
output(ostream &out) const {
|
||||||
out << "vertex data " << (void *)_source << " to "
|
out << "vertex data " << (void *)_source << " to "
|
||||||
<< *_modifier;
|
<< *_key._modifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
@ -200,24 +200,35 @@ private:
|
|||||||
typedef CycleDataReader<CDataCache> CDCacheReader;
|
typedef CycleDataReader<CDataCache> CDCacheReader;
|
||||||
typedef CycleDataWriter<CDataCache> CDCacheWriter;
|
typedef CycleDataWriter<CDataCache> CDCacheWriter;
|
||||||
|
|
||||||
public: // It is not clear why MSVC7 needs this class to be public.
|
public:
|
||||||
|
// The CacheKey class separates out just the part of CacheEntry that
|
||||||
|
// is used to key the cache entry within the map. We have this as a
|
||||||
|
// separate class so we can easily look up a new entry in the map,
|
||||||
|
// without having to execute the relatively expensive CacheEntry
|
||||||
|
// constructor.
|
||||||
|
class CacheKey {
|
||||||
|
public:
|
||||||
|
INLINE CacheKey(const GeomVertexFormat *modifier);
|
||||||
|
INLINE bool operator < (const CacheKey &other) const;
|
||||||
|
|
||||||
|
CPT(GeomVertexFormat) _modifier;
|
||||||
|
};
|
||||||
|
// It is not clear why MSVC7 needs this class to be public.
|
||||||
class CacheEntry : public GeomCacheEntry {
|
class CacheEntry : public GeomCacheEntry {
|
||||||
public:
|
public:
|
||||||
INLINE CacheEntry(const GeomVertexFormat *modifier);
|
|
||||||
INLINE CacheEntry(GeomVertexData *source,
|
INLINE CacheEntry(GeomVertexData *source,
|
||||||
const GeomVertexFormat *modifier);
|
const GeomVertexFormat *modifier);
|
||||||
ALLOC_DELETED_CHAIN(CacheEntry);
|
ALLOC_DELETED_CHAIN(CacheEntry);
|
||||||
INLINE bool operator < (const CacheEntry &other) const;
|
|
||||||
|
|
||||||
virtual void evict_callback();
|
virtual void evict_callback();
|
||||||
virtual void output(ostream &out) const;
|
virtual void output(ostream &out) const;
|
||||||
|
|
||||||
GeomVertexData *_source; // A back pointer to the containing GeomVertexData
|
GeomVertexData *_source; // A back pointer to the containing data.
|
||||||
CPT(GeomVertexFormat) _modifier;
|
CacheKey _key;
|
||||||
|
|
||||||
PipelineCycler<CDataCache> _cycler;
|
PipelineCycler<CDataCache> _cycler;
|
||||||
};
|
};
|
||||||
typedef pset<PT(CacheEntry), IndirectLess<CacheEntry> > Cache;
|
typedef pmap<const CacheKey *, PT(CacheEntry), IndirectLess<CacheKey> > Cache;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// This is the data that must be cycled between pipeline stages.
|
// This is the data that must be cycled between pipeline stages.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user