mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-25 13:35:54 +00:00
Clean up JSONCache
This commit is contained in:
@@ -1,127 +0,0 @@
|
||||
#ifndef JSONCACHE_H
|
||||
#define JSONCACHE_H
|
||||
|
||||
#define JC_OP_ACCOUNT_LINES 1
|
||||
#define JC_OP_ACCOUNT_OFFERS 2
|
||||
|
||||
class JSONCacheKey
|
||||
{
|
||||
private:
|
||||
uint256 mLedger;
|
||||
uint160 mObject;
|
||||
int mOperation;
|
||||
mutable int mLastUse;
|
||||
std::size_t mHash;
|
||||
|
||||
public:
|
||||
|
||||
JSONCacheKey(int op, const uint256& ledger, const uint160& object, int lastUse)
|
||||
: mLedger(ledger), mObject(object), mOperation(op), mLastUse(lastUse)
|
||||
{
|
||||
mHash = static_cast<std::size_t>(mOperation);
|
||||
mLedger.hash_combine(mHash);
|
||||
mObject.hash_combine(mHash);
|
||||
}
|
||||
|
||||
int compare(const JSONCacheKey& k) const
|
||||
{
|
||||
if (mHash < k.mHash) return -1;
|
||||
if (mHash > k.mHash) return 1;
|
||||
if (mOperation < k.mOperation) return -1;
|
||||
if (mOperation > k.mOperation) return 1;
|
||||
if (mLedger < k.mLedger) return -1;
|
||||
if (mLedger > k.mLedger) return 1;
|
||||
if (mObject < k.mObject) return -1;
|
||||
if (mObject > k.mObject) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool operator<(const JSONCacheKey &k) const { return compare(k) < 0; }
|
||||
bool operator>(const JSONCacheKey &k) const { return compare(k) > 0; }
|
||||
bool operator<=(const JSONCacheKey &k) const { return compare(k) <= 0; }
|
||||
bool operator>=(const JSONCacheKey &k) const { return compare(k) >= 0; }
|
||||
bool operator!=(const JSONCacheKey &k) const { return compare(k) != 0; }
|
||||
bool operator==(const JSONCacheKey &k) const { return compare(k) == 0; }
|
||||
|
||||
void touch(const JSONCacheKey& key) const { mLastUse = key.mLastUse; }
|
||||
bool expired(int expireTime) const { return mLastUse < expireTime; }
|
||||
|
||||
std::size_t getHash() const { return mHash; }
|
||||
};
|
||||
|
||||
inline std::size_t hash_value(const JSONCacheKey& key) { return key.getHash(); }
|
||||
|
||||
template <class Timer>
|
||||
class JSONCache
|
||||
{
|
||||
public:
|
||||
typedef boost::shared_ptr<Json::Value> data_t;
|
||||
|
||||
protected:
|
||||
boost::recursive_mutex mLock;
|
||||
boost::unordered_map<JSONCacheKey, data_t> mCache;
|
||||
int mCacheTime;
|
||||
uint64 mHits, mMisses;
|
||||
|
||||
public:
|
||||
JSONCache(int cacheTime) : mCacheTime(cacheTime), mHits(0), mMisses(0) { ; }
|
||||
|
||||
int upTime() { return Timer::getElapsedSeconds(); }
|
||||
|
||||
float getHitRate()
|
||||
{
|
||||
boost::recursive_mutex::scoped_lock sl(mLock);
|
||||
return (static_cast<float>(mHits) * 100) / (1.0f + mHits + mMisses);
|
||||
}
|
||||
|
||||
int getCount()
|
||||
{
|
||||
boost::recursive_mutex::scoped_lock sl(mLock);
|
||||
return mCache.size();
|
||||
}
|
||||
|
||||
data_t getEntry(int operation, const uint256& ledger, const uint160& object)
|
||||
{
|
||||
JSONCacheKey key(operation, ledger, object, upTime());
|
||||
|
||||
boost::recursive_mutex::scoped_lock sl(mLock);
|
||||
boost::unordered_map<JSONCacheKey, data_t>::iterator it = mCache.find(key);
|
||||
if (it == mCache.end())
|
||||
{
|
||||
++mMisses;
|
||||
return data_t();
|
||||
}
|
||||
++mHits;
|
||||
it->first.touch(key);
|
||||
return it->second;
|
||||
}
|
||||
|
||||
void storeEntry(int operation, const uint256& ledger, const uint160& object, const data_t& data)
|
||||
{
|
||||
JSONCacheKey key(operation, ledger, object, upTime());
|
||||
|
||||
boost::recursive_mutex::scoped_lock sl(mLock);
|
||||
mCache.insert(std::pair<JSONCacheKey, data_t>(key, data));
|
||||
}
|
||||
|
||||
void sweep()
|
||||
{
|
||||
int sweepTime = upTime();
|
||||
if (sweepTime < mCacheTime)
|
||||
return;
|
||||
sweepTime -= mCacheTime;
|
||||
|
||||
boost::recursive_mutex::scoped_lock sl(mLock);
|
||||
boost::unordered_map<JSONCacheKey, data_t>::iterator it = mCache.begin();
|
||||
while (it != mCache.end())
|
||||
{
|
||||
if (it->first.expired(sweepTime))
|
||||
it = mCache.erase(it);
|
||||
else
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -177,14 +177,16 @@ public:
|
||||
void sweepFetchPack();
|
||||
|
||||
float getJSONHitRate() { return mJSONCache.getHitRate(); }
|
||||
int getJSONEntries() { return mJSONCache.getCount(); }
|
||||
|
||||
void storeJSONCache(int operation, const uint256& ledger, const uint160& object,
|
||||
const boost::shared_ptr<Json::Value>& data)
|
||||
{ mJSONCache.storeEntry(operation, ledger, object, data); }
|
||||
// VFALCO TODO Rename this to getNumberOfCachedJSONItems or something similar
|
||||
int getJSONEntries() { return mJSONCache.getNumberOfEntries(); }
|
||||
|
||||
boost::shared_ptr<Json::Value> getJSONCache(int operation, const uint256& ledger, const uint160& object)
|
||||
{ return mJSONCache.getEntry(operation, ledger, object); }
|
||||
void storeJSONCache(JSONCache::Kind kind, const uint256& ledger, const uint160& object,
|
||||
const boost::shared_ptr <Json::Value>& data)
|
||||
{ mJSONCache.storeEntry(kind, ledger, object, data); }
|
||||
|
||||
boost::shared_ptr<Json::Value> getJSONCache(JSONCache::Kind kind, const uint256& ledger, const uint160& object)
|
||||
{ return mJSONCache.getEntry(kind, ledger, object); }
|
||||
|
||||
// network state machine
|
||||
void checkState(const boost::system::error_code& result);
|
||||
@@ -313,7 +315,7 @@ private:
|
||||
subMapType mSubTransactions; // all accepted transactions
|
||||
subMapType mSubRTTransactions; // all proposed and accepted transactions
|
||||
|
||||
JSONCache<UptimeTimerAdapter> mJSONCache;
|
||||
JSONCache mJSONCache;
|
||||
|
||||
TaggedCache< uint256, Blob , UptimeTimerAdapter > mFetchPack;
|
||||
uint32 mLastFetchPack;
|
||||
|
||||
@@ -1093,7 +1093,7 @@ Json::Value RPCHandler::doAccountLines(Json::Value jvRequest, int& cost, ScopedL
|
||||
jvResult["account"] = raAccount.humanAccountID();
|
||||
|
||||
boost::shared_ptr<Json::Value> jvsLines =
|
||||
theApp->getOPs().getJSONCache(JC_OP_ACCOUNT_LINES, lpLedger->getHash(), raAccount.getAccountID());
|
||||
theApp->getOPs().getJSONCache(JSONCache::kindLines, lpLedger->getHash(), raAccount.getAccountID());
|
||||
|
||||
if (!jvsLines)
|
||||
{
|
||||
@@ -1126,7 +1126,7 @@ Json::Value RPCHandler::doAccountLines(Json::Value jvRequest, int& cost, ScopedL
|
||||
}
|
||||
}
|
||||
|
||||
theApp->getOPs().storeJSONCache(JC_OP_ACCOUNT_LINES, lpLedger->getHash(),
|
||||
theApp->getOPs().storeJSONCache(JSONCache::kindLines, lpLedger->getHash(),
|
||||
raAccount.getAccountID(), jvsLines);
|
||||
}
|
||||
if (!bUnlocked)
|
||||
@@ -1199,13 +1199,13 @@ Json::Value RPCHandler::doAccountOffers(Json::Value jvRequest, int& cost, Scoped
|
||||
return rpcError(rpcACT_NOT_FOUND);
|
||||
|
||||
boost::shared_ptr<Json::Value> jvsOffers =
|
||||
theApp->getOPs().getJSONCache(JC_OP_ACCOUNT_OFFERS, lpLedger->getHash(), raAccount.getAccountID());
|
||||
theApp->getOPs().getJSONCache(JSONCache::kindOffers, lpLedger->getHash(), raAccount.getAccountID());
|
||||
|
||||
if (!jvsOffers)
|
||||
{
|
||||
jvsOffers = boost::make_shared<Json::Value>(Json::arrayValue);
|
||||
lpLedger->visitAccountItems(raAccount.getAccountID(), BIND_TYPE(&offerAdder, boost::ref(*jvsOffers), P_1));
|
||||
theApp->getOPs().storeJSONCache(JC_OP_ACCOUNT_OFFERS, lpLedger->getHash(), raAccount.getAccountID(), jvsOffers);
|
||||
theApp->getOPs().storeJSONCache(JSONCache::kindOffers, lpLedger->getHash(), raAccount.getAccountID(), jvsOffers);
|
||||
}
|
||||
if (!bUnlocked)
|
||||
MasterLockHolder.unlock();
|
||||
|
||||
Reference in New Issue
Block a user