mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-06 17:27:52 +00:00
Use abstract_clock and improved tests, in ResourceManager
Conflicts: Builds/VisualStudio2012/RippleD.vcxproj.filters
This commit is contained in:
@@ -2192,7 +2192,6 @@
|
||||
<ClInclude Include="..\..\src\ripple\resource\impl\Key.h" />
|
||||
<ClInclude Include="..\..\src\ripple\resource\impl\Kind.h" />
|
||||
<ClInclude Include="..\..\src\ripple\resource\impl\Logic.h" />
|
||||
<ClInclude Include="..\..\src\ripple\resource\impl\LogicType.h" />
|
||||
<ClInclude Include="..\..\src\ripple\resource\impl\Tuning.h" />
|
||||
<ClInclude Include="..\..\src\ripple\resource\ripple_resource.h" />
|
||||
<ClInclude Include="..\..\src\ripple\rocksdb\ripple_rocksdb.h" />
|
||||
|
||||
@@ -2559,9 +2559,6 @@
|
||||
<ClInclude Include="..\..\src\ripple\resource\api\LegacyFees.h">
|
||||
<Filter>[1] Ripple\resource\api</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\resource\impl\LogicType.h">
|
||||
<Filter>[1] Ripple\resource\impl</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\peerfinder\impl\LogicType.h">
|
||||
<Filter>[1] Ripple\peerfinder\impl</Filter>
|
||||
</ClInclude>
|
||||
|
||||
@@ -26,9 +26,6 @@ namespace Resource {
|
||||
struct Key;
|
||||
struct Entry;
|
||||
|
||||
/** Measures seconds from an unspecified fixed reference event in the past. */
|
||||
typedef int DiscreteTime;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
namespace ripple {
|
||||
namespace Resource {
|
||||
|
||||
typedef abstract_clock <std::chrono::seconds> clock_type;
|
||||
|
||||
// An entry in the table
|
||||
struct Entry : public List <Entry>::Node
|
||||
{
|
||||
@@ -57,14 +59,14 @@ struct Entry : public List <Entry>::Node
|
||||
}
|
||||
|
||||
// Balance including remote contributions
|
||||
int balance (DiscreteTime const now)
|
||||
int balance (clock_type::rep const now)
|
||||
{
|
||||
return local_balance.value (now) + remote_balance;
|
||||
}
|
||||
|
||||
// Add a charge and return normalized balance
|
||||
// including contributions from imports.
|
||||
int add (int charge, DiscreteTime const now)
|
||||
int add (int charge, clock_type::rep const now)
|
||||
{
|
||||
return local_balance.add (charge, now) + remote_balance;
|
||||
}
|
||||
@@ -85,10 +87,10 @@ struct Entry : public List <Entry>::Node
|
||||
Disposition disposition;
|
||||
|
||||
// Time of the last warning
|
||||
DiscreteTime lastWarningTime;
|
||||
clock_type::rep lastWarningTime;
|
||||
|
||||
// For inactive entries, time after which this entry will be erased
|
||||
DiscreteTime whenExpires;
|
||||
clock_type::rep whenExpires;
|
||||
};
|
||||
|
||||
std::ostream& operator<< (std::ostream& os, Entry const& v)
|
||||
|
||||
@@ -39,7 +39,7 @@ struct Import
|
||||
}
|
||||
|
||||
// When the imported data expires
|
||||
DiscreteTime whenExpires;
|
||||
clock_type::rep whenExpires;
|
||||
|
||||
// List of remote entries
|
||||
std::vector <Item> items;
|
||||
|
||||
@@ -26,6 +26,7 @@ namespace Resource {
|
||||
class Logic
|
||||
{
|
||||
public:
|
||||
typedef abstract_clock <std::chrono::seconds> clock_type;
|
||||
typedef boost::unordered_map <std::string, Import> Imports;
|
||||
typedef boost::unordered_map <Key, Entry, Key::hasher, Key::key_equal> Table;
|
||||
|
||||
@@ -53,13 +54,13 @@ public:
|
||||
typedef SharedData <State> SharedState;
|
||||
|
||||
SharedState m_state;
|
||||
DiscreteClock <DiscreteTime> m_clock;
|
||||
abstract_clock <std::chrono::seconds>& m_clock;
|
||||
Journal m_journal;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
Logic (DiscreteClock <DiscreteTime>::Source& source, Journal journal)
|
||||
: m_clock (source)
|
||||
Logic (clock_type& clock, Journal journal)
|
||||
: m_clock (clock)
|
||||
, m_journal (journal)
|
||||
{
|
||||
}
|
||||
@@ -212,7 +213,7 @@ public:
|
||||
|
||||
Json::Value getJson (int threshold)
|
||||
{
|
||||
DiscreteTime const now (m_clock());
|
||||
clock_type::rep const now (m_clock.elapsed());
|
||||
|
||||
Json::Value ret (Json::objectValue);
|
||||
SharedState::Access state (m_state);
|
||||
@@ -262,7 +263,7 @@ public:
|
||||
|
||||
Gossip exportConsumers ()
|
||||
{
|
||||
DiscreteTime const now (m_clock());
|
||||
clock_type::rep const now (m_clock.elapsed());
|
||||
|
||||
Gossip gossip;
|
||||
SharedState::Access state (m_state);
|
||||
@@ -288,7 +289,7 @@ public:
|
||||
|
||||
void importConsumers (std::string const& origin, Gossip const& gossip)
|
||||
{
|
||||
DiscreteTime const now (m_clock());
|
||||
clock_type::rep const now (m_clock.elapsed());
|
||||
|
||||
{
|
||||
SharedState::Access state (m_state);
|
||||
@@ -357,7 +358,7 @@ public:
|
||||
{
|
||||
SharedState::Access state (m_state);
|
||||
|
||||
DiscreteTime const now (m_clock());
|
||||
clock_type::rep const now (m_clock.elapsed());
|
||||
|
||||
for (List <Entry>::iterator iter (
|
||||
state->inactive.begin()); iter != state->inactive.end();)
|
||||
@@ -440,7 +441,7 @@ public:
|
||||
break;
|
||||
}
|
||||
state->inactive.push_back (entry);
|
||||
entry.whenExpires = m_clock() + secondsUntilExpiration;
|
||||
entry.whenExpires = m_clock.elapsed() + secondsUntilExpiration;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -455,7 +456,7 @@ public:
|
||||
|
||||
Disposition charge (Entry& entry, Charge const& fee, SharedState::Access& state)
|
||||
{
|
||||
DiscreteTime const now (m_clock());
|
||||
clock_type::rep const now (m_clock.elapsed());
|
||||
int const balance (entry.add (fee.cost(), now));
|
||||
m_journal.info <<
|
||||
"Charging " << entry << " for " << fee;
|
||||
@@ -465,7 +466,7 @@ public:
|
||||
bool warn (Entry& entry, SharedState::Access& state)
|
||||
{
|
||||
bool notify (false);
|
||||
DiscreteTime const now (m_clock());
|
||||
clock_type::rep const now (m_clock.elapsed());
|
||||
if (entry.balance (now) >= warningThreshold && now != entry.lastWarningTime)
|
||||
{
|
||||
charge (entry, feeWarning, state);
|
||||
@@ -483,7 +484,7 @@ public:
|
||||
bool disconnect (Entry& entry, SharedState::Access& state)
|
||||
{
|
||||
bool drop (false);
|
||||
DiscreteTime const now (m_clock());
|
||||
clock_type::rep const now (m_clock.elapsed());
|
||||
if (entry.balance (now) >= dropThreshold)
|
||||
{
|
||||
charge (entry, feeDrop, state);
|
||||
@@ -494,7 +495,7 @@ public:
|
||||
|
||||
int balance (Entry& entry, SharedState::Access& state)
|
||||
{
|
||||
return entry.balance (m_clock());
|
||||
return entry.balance (m_clock.elapsed());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
@@ -544,7 +545,7 @@ public:
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void writeList (
|
||||
DiscreteTime const now,
|
||||
clock_type::rep const now,
|
||||
PropertyStream::Set& items,
|
||||
List <Entry>& list)
|
||||
{
|
||||
@@ -563,7 +564,7 @@ public:
|
||||
|
||||
void onWrite (PropertyStream::Map& map)
|
||||
{
|
||||
DiscreteTime const now (m_clock());
|
||||
clock_type::rep const now (m_clock.elapsed());
|
||||
|
||||
SharedState::Access state (m_state);
|
||||
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_RESOURCE_LOGICTYPE_H_INCLUDED
|
||||
#define RIPPLE_RESOURCE_LOGICTYPE_H_INCLUDED
|
||||
|
||||
namespace ripple {
|
||||
namespace Resource {
|
||||
|
||||
template <class DiscreteClockSourceType>
|
||||
class LogicType
|
||||
: private BaseFromMember <DiscreteClockSourceType>
|
||||
, public Logic
|
||||
{
|
||||
public:
|
||||
typedef typename DiscreteClockSourceType::DiscreteClockType DiscreteClockType;
|
||||
|
||||
explicit LogicType (Journal journal)
|
||||
: Logic (BaseFromMember <DiscreteClockSourceType>::member(), journal)
|
||||
{
|
||||
}
|
||||
|
||||
DiscreteClockSourceType& clock()
|
||||
{
|
||||
return BaseFromMember <DiscreteClockSourceType>::member();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -26,12 +26,13 @@ class ManagerImp
|
||||
{
|
||||
public:
|
||||
Journal m_journal;
|
||||
LogicType <SimpleMonotonicClock> m_logic;
|
||||
Logic m_logic;
|
||||
|
||||
ManagerImp (Journal journal)
|
||||
: Thread ("Resource::Manager")
|
||||
, m_journal (journal)
|
||||
, m_logic (journal)
|
||||
, m_logic (get_abstract_clock <
|
||||
std::chrono::steady_clock, std::chrono::seconds> (), journal)
|
||||
{
|
||||
startThread ();
|
||||
}
|
||||
|
||||
@@ -23,6 +23,34 @@ namespace Resource {
|
||||
class Tests : public UnitTest
|
||||
{
|
||||
public:
|
||||
class TestLogic
|
||||
: private boost::base_from_member <manual_clock <std::chrono::seconds>>
|
||||
, public Logic
|
||||
|
||||
{
|
||||
private:
|
||||
typedef boost::base_from_member <
|
||||
manual_clock <std::chrono::seconds>> clock_type;
|
||||
|
||||
public:
|
||||
explicit TestLogic (Journal journal)
|
||||
: Logic (member, journal)
|
||||
{
|
||||
}
|
||||
|
||||
void advance ()
|
||||
{
|
||||
++member;
|
||||
}
|
||||
|
||||
manual_clock <std::chrono::seconds>& clock ()
|
||||
{
|
||||
return member;
|
||||
}
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void createGossip (Gossip& gossip)
|
||||
{
|
||||
int const v (10 + random().nextInt (10));
|
||||
@@ -38,11 +66,89 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void testImports ()
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
enum
|
||||
{
|
||||
maxLoopCount = 10000
|
||||
};
|
||||
|
||||
void testDrop (Journal j)
|
||||
{
|
||||
beginTestCase ("Warn/drop");
|
||||
|
||||
Tests::TestLogic logic (j);
|
||||
|
||||
Charge const fee (dropThreshold + 1);
|
||||
IPAddress const addr (
|
||||
IPAddress::from_string ("207.127.82.2"));
|
||||
|
||||
{
|
||||
Consumer c (logic.newInboundEndpoint (addr));
|
||||
|
||||
// Create load until we get a warning
|
||||
for (std::size_t n (maxLoopCount); n>=0; --n)
|
||||
{
|
||||
if (n == 0)
|
||||
{
|
||||
fail ("Loop count exceeded without warning");
|
||||
return;
|
||||
}
|
||||
|
||||
if (c.charge (fee) == warn)
|
||||
{
|
||||
pass ();
|
||||
break;
|
||||
}
|
||||
++logic.clock ();
|
||||
}
|
||||
|
||||
// Create load until we get dropped
|
||||
for (std::size_t n (maxLoopCount); n>=0; --n)
|
||||
{
|
||||
if (n == 0)
|
||||
{
|
||||
fail ("Loop count exceeded without dropping");
|
||||
return;
|
||||
}
|
||||
|
||||
if (c.charge (fee) == drop)
|
||||
{
|
||||
pass ();
|
||||
break;
|
||||
}
|
||||
++logic.clock ();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
{
|
||||
Consumer c (logic.newInboundEndpoint (addr));
|
||||
expect (c.disconnect ());
|
||||
}
|
||||
|
||||
for (std::size_t n (maxLoopCount); n>=0; --n)
|
||||
{
|
||||
Consumer c (logic.newInboundEndpoint (addr));
|
||||
if (n == 0)
|
||||
{
|
||||
fail ("Loop count exceeded without expiring black list");
|
||||
return;
|
||||
}
|
||||
|
||||
if (c.disposition() != drop)
|
||||
{
|
||||
pass ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void testImports (Journal j)
|
||||
{
|
||||
beginTestCase ("Imports");
|
||||
|
||||
LogicType <ManualClock> logic (journal());
|
||||
TestLogic logic (j);
|
||||
|
||||
Gossip g[5];
|
||||
|
||||
@@ -55,11 +161,11 @@ public:
|
||||
pass();
|
||||
}
|
||||
|
||||
void testImport ()
|
||||
void testImport (Journal j)
|
||||
{
|
||||
beginTestCase ("Import");
|
||||
|
||||
LogicType <ManualClock> logic (journal());
|
||||
TestLogic logic (j);
|
||||
|
||||
Gossip g;
|
||||
Gossip::Item item;
|
||||
@@ -72,37 +178,41 @@ public:
|
||||
pass();
|
||||
}
|
||||
|
||||
void testCharges ()
|
||||
void testCharges (Journal j)
|
||||
{
|
||||
beginTestCase ("Charge");
|
||||
|
||||
LogicType <ManualClock> logic (journal());
|
||||
TestLogic logic (j);
|
||||
|
||||
{
|
||||
IPAddress address (IPAddress::from_string ("207.127.82.1"));
|
||||
Consumer c (logic.newInboundEndpoint (address));
|
||||
logMessage ("Charging " + c.to_string() + " 10,000 units");
|
||||
c.charge (10000);
|
||||
Charge fee (1000);
|
||||
j.info <<
|
||||
"Charging " << c.to_string() << " " << fee << " per second";
|
||||
c.charge (fee);
|
||||
for (int i = 0; i < 128; ++i)
|
||||
{
|
||||
logMessage (
|
||||
"Time = " + String::fromNumber (logic.clock().now()) +
|
||||
", Balance = " + String::fromNumber (c.balance()));
|
||||
++logic.clock().now();
|
||||
j.info <<
|
||||
"Time= " << logic.clock().now().time_since_epoch() <<
|
||||
", Balance = " << c.balance();
|
||||
logic.advance();
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
IPAddress address (IPAddress::from_string ("207.127.82.2"));
|
||||
Consumer c (logic.newInboundEndpoint (address));
|
||||
logMessage ("Charging " + c.to_string() + " 1000 units per second");
|
||||
Charge fee (1000);
|
||||
j.info <<
|
||||
"Charging " << c.to_string() << " " << fee << " per second";
|
||||
for (int i = 0; i < 128; ++i)
|
||||
{
|
||||
c.charge (1000);
|
||||
logMessage (
|
||||
"Time = " + String::fromNumber (logic.clock().now()) +
|
||||
", Balance = " + String::fromNumber (c.balance()));
|
||||
++logic.clock().now();
|
||||
c.charge (fee);
|
||||
j.info <<
|
||||
"Time= " << logic.clock().now().time_since_epoch() <<
|
||||
", Balance = " << c.balance();
|
||||
logic.advance();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,12 +221,16 @@ public:
|
||||
|
||||
void runTest ()
|
||||
{
|
||||
testCharges();
|
||||
testImports();
|
||||
testImport();
|
||||
//Journal j (journal());
|
||||
Journal j;
|
||||
|
||||
testDrop (j);
|
||||
testCharges (j);
|
||||
testImports (j);
|
||||
testImport (j);
|
||||
}
|
||||
|
||||
Tests () : UnitTest ("ResourceManager", "ripple", runManual)
|
||||
Tests () : UnitTest ("ResourceManager", "ripple")
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
@@ -22,9 +22,9 @@
|
||||
#include "ripple_resource.h"
|
||||
|
||||
#include "../algorithm/api/DecayingSample.h"
|
||||
#include "../algorithm/api/DiscreteClock.h"
|
||||
|
||||
#include "beast/modules/beast_core/system/BeforeBoost.h"
|
||||
#include <boost/utility/base_from_member.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
|
||||
#include "impl/Fees.cpp"
|
||||
@@ -35,7 +35,6 @@
|
||||
# include "impl/Import.h"
|
||||
#include "impl/Charge.cpp"
|
||||
# include "impl/Logic.h"
|
||||
# include "impl/LogicType.h"
|
||||
#include "impl/Consumer.cpp"
|
||||
#include "impl/LegacyFees.cpp"
|
||||
#include "impl/Manager.cpp"
|
||||
|
||||
Reference in New Issue
Block a user