-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Reduce peer message traffic for ledger data #5126
base: develop
Are you sure you want to change the base?
Changes from 7 commits
f0cf1fd
756cad9
8a17f16
226cb56
d5ec2d3
ecfa396
e490e57
30eee9b
978fecd
b8b7b31
43b6e3e
813ef05
89f5a67
d7e2d70
29de22e
e250086
da4a30c
eee8184
85dcf70
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
//------------------------------------------------------------------------------ | ||
/* | ||
This file is part of rippled: https://github.com/ripple/rippled | ||
Copyright (c) 2024 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_BASICS_CANPROCESS_H_INCLUDED | ||
#define RIPPLE_BASICS_CANPROCESS_H_INCLUDED | ||
|
||
/** RAII class to check if an Item is already being processed on another thread, | ||
* as indicated by it's presence in a Collection. | ||
* | ||
* If the Item is not in the Collection, it will be added under lock in the | ||
* ctor, and removed under lock in the dtor. The object will be considered | ||
* "usable" and evaluate to `true`. | ||
* | ||
* If the Item is in the Collection, no changes will be made to the collection, | ||
* and the CanProcess object will be considered "unusable". | ||
* | ||
* It's up to the caller to decide what "usable" and "unusable" mean. (e.g. | ||
* Process or skip a block of code, or set a flag.) | ||
* | ||
* The current use is to avoid lock contention that would be involved in | ||
* processing something associated with the Item. | ||
* | ||
* Examples: | ||
* | ||
* void IncomingLedgers::acquireAsync(LedgerHash const& hash, ...) | ||
* { | ||
* if (CanProcess check{acquiresMutex_, pendingAcquires_, hash}) | ||
* { | ||
* acquire(hash, ...); | ||
* } | ||
* } | ||
* | ||
* bool | ||
* NetworkOPsImp::recvValidation( | ||
* std::shared_ptr<STValidation> const& val, | ||
* std::string const& source) | ||
* { | ||
* CanProcess check( | ||
* validationsMutex_, pendingValidations_, val->getLedgerHash()); | ||
* BypassAccept bypassAccept = | ||
* check.canProcess() ? BypassAccept::no : BypassAccept::yes; | ||
* handleNewValidation(app_, val, source, bypassAccept, m_journal); | ||
* } | ||
* | ||
*/ | ||
template <class Mutex, class Collection, class Item> | ||
class CanProcess | ||
{ | ||
public: | ||
CanProcess(Mutex& mtx, Collection& collection, Item const& item) | ||
: mtx_(mtx), collection_(collection), item_(item), canProcess_(insert()) | ||
{ | ||
} | ||
|
||
~CanProcess() | ||
{ | ||
if (canProcess_) | ||
{ | ||
std::unique_lock<Mutex> lock_(mtx_); | ||
collection_.erase(item_); | ||
} | ||
} | ||
|
||
bool | ||
canProcess() const | ||
{ | ||
return canProcess_; | ||
} | ||
|
||
operator bool() const | ||
{ | ||
return canProcess_; | ||
} | ||
|
||
private: | ||
bool | ||
insert() | ||
{ | ||
std::unique_lock<Mutex> lock_(mtx_); | ||
bool exists = collection_.contains(item_); | ||
if (!exists) | ||
collection_.insert(item_); | ||
return !exists; | ||
} | ||
|
||
Mutex& mtx_; | ||
Collection& collection_; | ||
Item const item_; | ||
bool const canProcess_; | ||
}; | ||
|
||
#endif |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -623,6 +623,13 @@ to_string(base_uint<Bits, Tag> const& a) | |
return strHex(a.cbegin(), a.cend()); | ||
} | ||
|
||
template <std::size_t Bits, class Tag> | ||
inline std::string | ||
to_short_string(base_uint<Bits, Tag> const& a) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [nit]: Adding checks for the to_short_string in the base_unit_test next to existing to_string cases would be good. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wouldn't call that a nit. Missing test coverage is pretty significant. Thanks for catching it. Fixed. |
||
{ | ||
return strHex(a.cbegin(), a.cend()).substr(0, 8) + "..."; | ||
} | ||
|
||
template <std::size_t Bits, class Tag> | ||
inline std::ostream& | ||
operator<<(std::ostream& out, base_uint<Bits, Tag> const& u) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would avoid extra lookup
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch. Fixed.