/*
* Copyright 2001-2007 Internet2
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
/**
* MemoryStorageService.cpp
- *
+ *
* In-memory "persistent" storage, suitable for simple applications.
*/
#include "internal.h"
+#include "logging.h"
#include "util/NDC.h"
#include "util/StorageService.h"
#include "util/Threads.h"
#include "util/XMLHelper.h"
-#include <log4cpp/Category.hh>
+#include <memory>
#include <xercesc/util/XMLUniDefs.hpp>
+using namespace xmltooling::logging;
using namespace xmltooling;
-using namespace log4cpp;
using namespace std;
+using xercesc::DOMElement;
+
namespace xmltooling {
class XMLTOOL_DLLLOCAL MemoryStorageService : public StorageService
{
public:
MemoryStorageService(const DOMElement* e);
virtual ~MemoryStorageService();
-
- void createString(const char* context, const char* key, const char* value, time_t expiration);
+
+ bool createString(const char* context, const char* key, const char* value, time_t expiration);
int readString(const char* context, const char* key, string* pvalue=NULL, time_t* pexpiration=NULL, int version=0);
int updateString(const char* context, const char* key, const char* value=NULL, time_t expiration=0, int version=0);
bool deleteString(const char* context, const char* key);
-
- void createText(const char* context, const char* key, const char* value, time_t expiration) {
+
+ bool createText(const char* context, const char* key, const char* value, time_t expiration) {
return createString(context, key, value, expiration);
}
int readText(const char* context, const char* key, string* pvalue=NULL, time_t* pexpiration=NULL, int version=0) {
bool deleteText(const char* context, const char* key) {
return deleteString(context, key);
}
-
+
void reap(const char* context);
void updateContext(const char* context, time_t expiration);
void deleteContext(const char* context) {
private:
void cleanup();
-
+
struct XMLTOOL_DLLLOCAL Record {
Record() : expiration(0), version(1) {}
Record(const string& s, time_t t) : data(s), expiration(t), version(1) {}
time_t expiration;
int version;
};
-
+
struct XMLTOOL_DLLLOCAL Context {
Context() {}
Context(const Context& src) {
shutdown_wait->signal();
cleanup_thread->join(NULL);
+ delete cleanup_thread;
delete shutdown_wait;
delete m_lock;
}
MemoryStorageService* cache = reinterpret_cast<MemoryStorageService*>(cache_p);
#ifndef WIN32
- // First, let's block all signals
+ // First, let's block all signals
Thread::mask_all_signals();
#endif
shutdown_wait->timedwait(mutex.get(), m_cleanupInterval);
if (shutdown)
break;
-
+
unsigned long count=0;
time_t now = time(NULL);
m_lock->wrlock();
SharedLock locker(m_lock, false);
for (map<string,Context>::iterator i=m_contextMap.begin(); i!=m_contextMap.end(); ++i)
count += i->second.reap(now);
-
+
if (count)
m_log.info("purged %d expired record(s) from storage", count);
}
return count;
}
-void MemoryStorageService::createString(const char* context, const char* key, const char* value, time_t expiration)
+bool MemoryStorageService::createString(const char* context, const char* key, const char* value, time_t expiration)
{
Context& ctx = writeContext(context);
SharedLock locker(m_lock, false);
if (i!=ctx.m_dataMap.end()) {
// Not yet expired?
if (time(NULL) < i->second.expiration)
- throw IOException("attempted to insert a record with duplicate key ($1)", params(1,key));
+ return false;
// It's dead, so we can just remove it now and create the new record.
ctx.m_dataMap.erase(i);
}
-
+
ctx.m_dataMap[key]=Record(value,expiration);
-
+
m_log.debug("inserted record (%s) in context (%s)", key, context);
+ return true;
}
int MemoryStorageService::readString(const char* context, const char* key, string* pvalue, time_t* pexpiration, int version)
return 0;
else if (time(NULL) >= i->second.expiration)
return 0;
-
+
if (version > 0 && version != i->second.version)
return -1; // caller's out of sync
i->second.data = value;
++(i->second.version);
}
-
+
if (expiration && expiration != i->second.expiration)
i->second.expiration = expiration;
{
Context& ctx = writeContext(context);
SharedLock locker(m_lock, false);
-
+
// Find the record.
map<string,Record>::iterator i=ctx.m_dataMap.find(key);
if (i!=ctx.m_dataMap.end()) {