82 #include "packets/ObjectCaching.h"
97 for(; cur != end; cur++) {
114 objectCaching_CachedObject_spec spec;
116 spec.objectID = objectID->
Clone();
118 spec.timestamp = timestamp;
119 spec.version = version;
121 return(spec.Encode());
142 if ( !objectID->
visit( v ) ) {
143 sLog.Error(
"Cached Obj Mgr",
"Failed to convert cache hind object ID into collapsed string:");
144 objectID->
Dump(CACHE__DUMP,
" ");
185 if (!cache.
Decode(in_cached_data)) {
186 sLog.Error(
"CachedObjMgr",
"Failed to decode stream");
206 PyRep* cached_data(*in_cached_data);
207 *in_cached_data =
nullptr;
221 sLog.Error(
"Cached Obj Mgr",
"Failed to marshal or deflate new cache object." );
247 sLog.Debug(
"CachedObjMgr",
"Destroying old cached object with ID '%s' of length %u with checksum 0x%x", str.c_str(), res->second->cache->content().size(), res->second->version);
251 sLog.Debug(
"CachedObjMgr",
"Registering new cached object with ID '%s' of length %u with checksum 0x%x", str.c_str(), r->
cache->
content().
size(), r->
version);
273 return res->second->EncodeHint();
295 co.
version = res->second->version;
299 co.
cache = res->second->cache;
301 if (res->second->cache->content().size() == 0 || res->second->cache->content()[0] ==
MarshalHeaderByte)
306 sLog.Debug(
"CachedObjMgr",
"Returning cached object '%s' with checksum 0x%x", str.c_str(), co.
version);
323 return ( res->second->version == version
324 && res->second->timestamp == timestamp);
345 std::string filename(cacheDir);
346 filename +=
"/" + str +
".cache";
348 FILE *f = fopen(filename.c_str(),
"rb");
354 if (fread(&header,
sizeof(header), 1, f) != 1) {
410 std::string filename(cacheDir);
413 filename +=
".cache";
415 FILE *f = fopen(filename.c_str(),
"wb");
421 header.
timestamp = res->second->timestamp;
422 header.
version = res->second->version;
424 header.
length = res->second->cache->content().size();
426 if (fwrite(&header,
sizeof(header), 1, f) != 1) {
431 if (fwrite(&res->second->cache->content()[0],
sizeof(
uint8), header.
length, f) != header.
length) {
470 std::string abs_fname =
"../data/cache/";
478 FILE* f = fopen( abs_fname,
"rb" );
480 if ( f ==
nullptr ) {
481 sLog.Error(
"CachedObjMgr",
"Unable to open cache file '%s' for oname '%s': %s", abs_fname, oname, strerror( errno ) );
486 if ( file_length == 0 )
488 sLog.Error(
"CachedObjMgr",
"Unable to stat cache file '%s' for oname '%s'", abs_fname, oname );
493 Buffer* buf =
new Buffer(static_cast<size_t>(file_length));
495 if ( file_length != fread( &( *buf )[0],
sizeof(
uint8 ), static_cast<size_t>(file_length), f ) ) {
496 sLog.Error(
"CachedObjMgr",
"Unable to read cache file '%s' for oname '%s%': %s", abs_fname, oname, strerror( errno ) );
503 sLog.Debug(
"CachedObjMgr",
"Loaded cache file for '%s': length %u", oname, file_length );
550 std::string::size_type epos = into.find(
'=');
551 if (epos != std::string::npos)
625 fprintf(into,
"%sCached Object:\n", pfx);
626 fprintf(into,
"%s ObjectID:\n", pfx);
629 fprintf(into,
"%s Version: %u\n", pfx,
version);
630 fprintf(into,
"%s NodeID: %u\n", pfx,
nodeID);
631 fprintf(into,
"%s Shared: %s\n", pfx,
shared?
"yes":
"no");
632 fprintf(into,
"%s Compressed: %s\n", pfx,
compressed?
"yes":
"no");
634 fprintf(into,
"%s Contents:\n", pfx);
643 fprintf(into,
"%sCached Object:\n", pfx);
644 fprintf(into,
"%s ObjectID:\n", pfx);
647 fprintf(into,
"%s Version: %u\n", pfx,
version);
648 fprintf(into,
"%s NodeID: %u\n", pfx,
nodeID);
649 fprintf(into,
"%s Shared: %s\n", pfx,
shared?
"yes":
"no");
650 fprintf(into,
"%s Compressed: %s\n", pfx,
compressed?
"yes":
"no");
652 fprintf(into,
"%s Contents:\n", pfx);
666 if (ss->
decoded() ==
nullptr) {
667 sLog.Error(
"PyCachedObjectDecoder",
"Unable to decode initial stream for PycachedObject");
674 sLog.Error(
"PyCachedObjectDecoder",
"Cache substream does not contain an object: %s", ss->
decoded()->
TypeString());
690 if (args->
items.size() != 7) {
691 sLog.Error(
"PyCachedObjectDecoder",
"Cache object's args tuple has %lu elements instead of 7", args->
items.size());
697 if (!args->
items[0]->IsTuple()) {
698 sLog.Error(
"PyCachedObjectDecoder",
"Cache object's arg %d is not a Tuple: %s", 0, args->
items[0]->TypeString());
710 if (!args->
items[2]->IsInt()) {
711 sLog.Error(
"PyCachedObjectDecoder",
"Cache object's arg %d is not an Integer: %s", 2, args->
items[2]->TypeString());
716 if (!args->
items[3]->IsInt()) {
717 sLog.Error(
"PyCachedObjectDecoder",
"Cache object's arg %d is not an Integer: %s", 3, args->
items[3]->TypeString());
722 if (!args->
items[5]->IsInt()) {
723 sLog.Error(
"PyCachedObjectDecoder",
"Cache object's arg %d is not a : %s", 5, args->
items[5]->TypeString());
729 if (!objVt->
items[0]->IsInt()) {
730 sLog.Error(
"PyCachedObjectDecoder",
"Cache object's version tuple %d is not an Integer: %s", 0, objVt->
items[0]->TypeString());
735 if (!objVt->
items[1]->IsInt()) {
736 sLog.Error(
"PyCachedObjectDecoder",
"Cache object's version tuple %d is not an Integer: %s", 1, objVt->
items[1]->TypeString());
750 shared = ( sharedr->value() != 0 );
754 if (args->
items[4]->IsSubStream()) {
757 args->
items[4] =
nullptr;
758 }
else if (args->
items[4]->IsBuffer()) {
762 }
else if (args->
items[4]->IsString()) {
767 sLog.Error(
"PyCachedObjectMgr",
"Cache object's arg %d is not a substream or buffer: %s", 4, args->
items[4]->TypeString());
812 return new PyObject(
"objectCaching.CachedObject", arg_tuple );
822 arg_tuple->
items[2] = versiont;
824 return new PyObject(
"util.CachedObject", arg_tuple );
844 fprintf(into,
"%sCached Call: (empty right now) \n", pfx);
846 fprintf(into,
"%s Contents:\n", pfx);
859 if (ss->
decoded() ==
nullptr) {
860 sLog.Error(
"PyCachedCall",
"Unable to decode initial stream for PyCachedCall");
866 sLog.Error(
"PyCachedCall",
"Cached call substream does not contain a dict: %s", ss->
decoded()->
TypeString());
875 for(; cur != end; cur++) {
876 if (!cur->first->IsString())
884 return (
result !=
nullptr);
bool IsCacheUpToDate(const PyRep *objectID, uint32 version, int64 timestamp)
CachedObjMap::const_iterator CachedObjMapConstItr
bool MarshalDeflate(const PyRep *rep, Buffer &into, const uint32 deflationLimit)
PyCachedCall * LoadCachedCall(const char *filename, const char *oname)
void GetCacheFileName(PyRep *key, std::string &into)
bool HaveCached(const std::string &objectID) const
const Buffer & content() const
Get the const PyBuffer content.
virtual PyRep * Clone() const =0
Clones object.
PyCachedObject * Clone() const
static const uint32 HackCacheNodeID
PyRep * Clone() const
Clones object.
PyObject * MakeCacheHint(const PyRep *objectID)
bool Marshal(const PyRep *rep, Buffer &into)
void Dump(FILE *into, const char *pfx) const
Dumps object to file.
void UpdateCache(const std::string &objectID, PyRep **in_cached_data)
PyRep * arguments() const
void SafeDelete(T *&p)
Deletes and nullifies a pointer.
PyCachedCall * Clone() const
#define sLog
Evaluates to a NewLog instance.
Generic class for buffers.
PySubStream * LoadCachedFile(const char *obj_name)
PyTuple * new_tuple(int64 arg1)
void Dump(FILE *into, const char *pfx, bool contents_too=false)
bool SaveCachedToFile(const std::string &cacheDir, const std::string &objectID) const
void UpdateCacheFromSS(const std::string &objectID, PySubStream **in_cached_data)
const uint32 CacheFileMagic
CachedObjMap m_cachedObjects
CachedObjMap::iterator CachedObjMapItr
void InvalidateCache(const PyRep *objectID)
static uint32 Generate(const uint8 *buf, size_t bufsize)
void Dump(FILE *into, const char *pfx, bool contents_too=false)
static void encode(FILE *, std::string &, bool add_crlf=true)
if(sConfig.world.saveOnMove)
const_iterator begin() const
static std::string OIDToString(const PyRep *objectID)
static const uint8 MarshalHeaderByte
storage_type::const_iterator const_iterator
void _UpdateCache(const PyRep *objectID, PyBuffer **buffer)
PyObject * EncodeHint() const
const std::string & content() const
Get the PyString content.
void Dump(FILE *into, const char *pfx, bool contents_too=false)
const_iterator end() const
bool Decode(PySubStream **ss)
PyObject * GetCachedObject(const PyRep *objectID)
PyCachedObjectDecoder * LoadCachedObject(const char *filename, const char *oname)
typeID Spawn an NPC with the specified type text Search for items matching the specified query() type() key(value)-Send an OnRemoteMessage" ) COMMAND( setbpattr
const char * TypeString() const
bool LoadCachedFromFile(const std::string &cacheDir, const std::string &objectID)
int64 filesize(const char *filename)
Obtains filesize.
virtual bool visit(PyVisitor &v) const =0
Visits object.
bool Decode(PySubStream **ss)