Compare commits

...

575 Commits

Author SHA1 Message Date
Vinnie Falco
7b417b9d51 Set version to 0.28.1-rc1 2015-05-12 17:21:48 -07:00
Vinnie Falco
cc05e5727d Merge release into develop 2015-05-12 17:20:43 -07:00
Vinnie Falco
764a8f2644 Set version to 0.28.1-b10 2015-05-12 12:47:56 -07:00
JoelKatz
a15785eb64 Reduce severity of some logging messages 2015-05-12 12:47:56 -07:00
Vinnie Falco
688f8c5f3f Add historical ledger fetches per minute to get_counts 2015-05-12 12:47:56 -07:00
Vinnie Falco
dde5ccf7fa Add DecayWindow implementation 2015-05-12 12:47:55 -07:00
Vinnie Falco
d5a6313c71 Add RangeSet::lebesgue_sum 2015-05-12 09:50:12 -07:00
Vinnie Falco
f030aab759 Set version to 0.28.1-b9 2015-05-11 18:14:45 -07:00
JoelKatz
4393f98a2c History fetch changes:
* Don't pollute ledger cache with history
* Avoid race condition when getting ledger sequence numbers
* Make fetch packs larger
2015-05-11 18:14:45 -07:00
JoelKatz
c377d6c94b InboundLedgers improvements:
* Change findCreate to acquire
* Return Ledger rather than InboundLedger
2015-05-11 18:14:45 -07:00
JoelKatz
16aa015682 Fix off-by-one error in SHAMapNodeID:
Limit is 64 inner nodes at depth 0-63, and one leaf at depth 64
2015-05-11 18:14:45 -07:00
Miguel Portilla
9cded76cf0 Fix RPC ledger synchronization requirements:
* Better rules specific to each lookup case:
* By hash: Any ledger found by hash is valid.
* By numeric index: If rippled is out of sync, and the index is after the
* validated ledger, return "InsufficientNetworkMode" error.
* By named index: If rippled is out of sync, or closed/current is requested and significantly older than the validated ledger, return "InsufficientNetworkMode" error.
2015-05-11 18:14:45 -07:00
Vinnie Falco
4ad07bb6b2 Fix hops adjustment for validations 2015-05-11 18:14:45 -07:00
David Schwartz
d0b28a6700 Compute validated ledger age from signing time 2015-05-11 18:14:39 -07:00
Vinnie Falco
18299c3f7a Tidy up PeerSet:
* Move PeerSet to overlay/
* Remove unused functions
* Make some public members private
* Rename some functions
* Add comments
2015-05-11 12:06:14 -07:00
Miguel Portilla
ca07a1230b Add filtering to Account Objects (RIPD-868) 2015-05-11 11:58:35 -07:00
Edward Hennis
e0ad66d967 Fail Travis if scons vcxproj produces differences 2015-05-11 11:56:45 -07:00
seelabs
5615c4a2a7 Force scons to include soci version file:
Running `scons vcxproj` will sometimes include
soci's version.h and sometimes it will not. This
patch forces it to always include the file.
2015-05-11 11:56:42 -07:00
Nik Bougalis
d7fbef6764 Set version to 0.28.1-b8 2015-05-06 14:00:34 -07:00
JoelKatz
e95bda3bdf Peer latency tracking (RIPD-879):
Track peer latency, report in RPC, make peer selection for
fetching latency aware.

This also cleans up the PeerImp timer to minimize
resetting. Indirect routing is made latency-aware as well.
2015-05-06 13:38:59 -07:00
JoelKatz
c010a85ef5 Check the correct progress flag on transaction root node receipt 2015-05-06 13:38:59 -07:00
MarkusTeufelberger
798d36efcf Fix typo in LedgerMaster.cpp 2015-05-06 13:25:50 -07:00
Nik Bougalis
2d44c8568f Eliminate need for ledger in delivered_amount calculation (RIPD-860) 2015-05-06 13:25:50 -07:00
Nik Bougalis
7232bdb40c Reduce PeerFinder log verbosity 2015-05-06 13:25:50 -07:00
David Schwartz
45f092488a Simplify InboundLedger expiration (RIPD-873)
Let sweep logic remove obsolete ledger requests.
Touch inbound ledgers to prevent sweeping on requests.
Update sequence number if possible.
2015-05-06 13:25:50 -07:00
JoelKatz
4244e1070d Improvements to STParsedJSON:
* Cleanups and reduction of copying
* Add STArray::back, operator[], push_back(&&)
* Add make_stvar
* Rework STParsedJSON
* Fix code and unit tests that use STParsedJSON
* STTx move constructor
2015-05-06 13:11:24 -07:00
Nik Bougalis
5a7fa8cfa9 Reduce STAmount public interface (RIPD-867):
The STAmount class includes a number of functions which serve as thin
wrappers, which are unused or used only in one place, or which break
encapsulation by exposing internal implemenation details. Removing
such functions simplifies the interface of the class and ensures
consistency.

* getSNValue and getNValue are now free functions
* canonicalizeRound is no longer exposed
* Removed addRound and subRound
* Removed overloads of multiply, mulRound, divide and divRound
2015-05-06 13:11:24 -07:00
Josh Juran
daf4f8fcde Remove wallet_accounts and generator maps (RIPD-804):
* Remove the deprecated wallet_accounts command.
 * Remove dead code for generator maps.
 * Remove the help for the obsolete wallet_add and wallet_claim commands
   (which have already been removed).
2015-05-06 13:11:24 -07:00
Miguel Portilla
d182d1455e Relax RPC ledger synchronization requirements (RIPD-27, RIPD-840):
This enhances the reporting capability of RPC::LookupLedger and reduces
the requirement of a current ledger for many RPC commands.

The perceived up-time of client handlers improves since requests will
not depend on the server being fully synced.
2015-05-06 13:10:47 -07:00
Vinnie Falco
dc2260adbe Set version to 0.28.1-b7 2015-04-29 16:44:47 -07:00
Vinnie Falco
83a01e0c7d Set hopsAware version cutoff to 0.28.1-b7 2015-04-29 16:44:05 -07:00
Tom Ritchford
53c1269ebd Set version to 0.28.1-b6 2015-04-29 14:34:54 -04:00
Nik Bougalis
f8bfe3a550 Terminate process on SIGINT in all cases 2015-04-29 14:34:54 -04:00
Vinnie Falco
90bb53af20 Structured Overlay support for TTL limited messages:
When the [overlay] configuration key "expire" is set to 1, proposals
and validations will include a hops field. The hops is incremented with
each relay. Messages with a hop count will be dropped when they exceed
the TTL (Time to Live). Messages containing a hops field will not be
relayed or broadcast to older versions of rippled that don't understand
the field.

This change will not affect normal operation of the network or rippled
instances that do not set "expire" to 1.
2015-04-29 14:34:54 -04:00
Vinnie Falco
c77a2f335a Tidy up some business logic:
* Add OverlayImpl::for_each to tidy up some call sites
* Add comment about computing the unique ID for message routing
* Remove unused code
2015-04-29 14:34:53 -04:00
Vinnie Falco
8e34a1f6a7 Tidy up aged container declarations 2015-04-29 14:34:53 -04:00
Tom Ritchford
2564b62f5c Fix C++ style issues.
* Restrict files to 80 columns.
* Function names in GenerateDeterministicKey now start with lower case.
* Remove deprecated boost::format calls.
2015-04-29 14:34:53 -04:00
seelabs
a7598c5610 Remove unused database table (RIPD-755) 2015-04-29 14:34:52 -04:00
seelabs
8377f2516b Cache and apply account credits after payment processing (RIPD-821):
Credits made to any account during the processing of a payment are delayed until
the payment completes, enforcing a new invariant: liquidity for any paths
during a payment's execution may never increase. This eliminates the need for special
code to handle a variety of corner cases where consuming liquidity in one path
increases liquidity in others.
2015-04-29 14:34:52 -04:00
Vinnie Falco
7efd0ab0d6 Set version to 0.28.0 2015-04-24 18:57:36 -07:00
Vinnie Falco
14d38a1a8d Fix --rpc_ip and --rpc_port (RIPD-679)
This reverts commit 2b040569e7.
2015-04-24 18:57:04 -07:00
seelabs
c8447c190c Report the inbound listening port during crawl (RIPD-866) 2015-04-24 18:55:53 -07:00
Mark Travis
aa5d16b3d8 Skip inefficent SQL query (RIPD-870):
For large data sets the JOIN may not make forward progress in time.
This prevents the deletion of those entries in the database during
online delete. The number of such entries is very small compared to
the total size of the data anyway. A future version will address
this more thoroughly.
2015-04-24 18:55:49 -07:00
Vinnie Falco
fd1135315c Set version to 0.28.1-b5 2015-04-24 18:44:30 -07:00
Vinnie Falco
98c915b2ca Fix --rpc_ip and --rpc_port (RIPD-679)
This reverts commit 2b040569e7.
2015-04-24 18:44:30 -07:00
seelabs
9114f3d2e6 Report the inbound listening port during crawl (RIPD-866) 2015-04-24 18:19:10 -07:00
Mark Travis
5b0109055d Skip inefficent SQL query (RIPD-870):
For large data sets the JOIN may not make forward progress in time.
This prevents the deletion of those entries in the database during
online delete. The number of such entries is very small compared to
the total size of the data anyway. A future version will address
this more thoroughly.
2015-04-24 17:21:27 -07:00
Tom Ritchford
5a3168c9ff Set version to 0.28.1-b4 2015-04-23 16:47:23 -04:00
seelabs
a14f29f84f Remove obsolete code 2015-04-23 16:47:23 -04:00
Tom Ritchford
6c1190a361 Remove unnecessary thread in Soci (RIPD-862). 2015-04-23 16:47:22 -04:00
Howard Hinnant
100a76f0e8 Remove nested types SField::ref and SField::ptr...
* This silences a warning about a redundant cv-qualifier.
* This makes future coding mistakes about redundant
  cv-qualifiers much less likely.
* This makes the code easier to read.
2015-04-23 16:47:22 -04:00
JoelKatz
47482acf83 In consensus, get relative times from a steady clock (RIPD-859)
Using the system clock to get relative times for consensus
timing can result in performance issues if the system time
changes frequently.
2015-04-23 16:47:21 -04:00
Nik Bougalis
54ef4ee6ef Reduce severity level of offer cancellation logging 2015-04-23 16:47:20 -04:00
seelabs
2389abc295 Fix ownership of memory buffers in StatsDCollector (RIPD-756):
* Ownership of buffer memory in StatsDCollector is passed to the
boost::asio callback function. Before this, the memory may have been
freed before async_send was finished with the memory.
2015-04-23 16:47:20 -04:00
Nik Bougalis
67c666b033 Clean up LedgerEntrySet and TransactionEngine:
* Reduce public interfaces
* Remove wrapper functions
* Remove freeze timed cutover code
* Return results directly instead of via ref parameters
2015-04-23 16:47:19 -04:00
Vinnie Falco
5ce3ed3555 Set version to 0.28.1-b3 2015-04-21 14:01:44 -07:00
Nik Bougalis
d30b32fcde Set TX processing change date to 2015-05-12 13:00:00PDT 2015-04-21 14:01:25 -07:00
Miguel Portilla
568e4cebda Fix check for current ledger ID in RPC 2015-04-21 14:01:18 -07:00
Tom Ritchford
29d644e9d3 Fix WebSockets treatment of ping timer:
This solves a problem that caused a hang on shutdown related to
the lifetime of the ping timer completion handlers used in WebSockets.

* Turn the ping timer back on
* Use std::weak_ptr for WebSockets timer callbacks.
* Disable WebSocket pings if frequency in the .cfg is non-positive.
2015-04-21 14:01:13 -07:00
Torrie Fischer
2dbb7301fb Fix circleci 2015-04-21 14:01:09 -07:00
seelabs
d2cba1c54f Tidy up SQLite table creation:
* Check if tables and indexes exist
* Remove commands for unused table
2015-04-21 14:01:05 -07:00
seelabs
6a0c26a709 Fix return value when looking up non existent transactions 2015-04-21 14:01:00 -07:00
JoelKatz
e44ae6af93 Give ledger data requests their own job type:
This gives requests for ledger data (and transaction set data)
from peers a separate job type and prioritizes it appropriately.
Previously it was lumped in with fetch packs which have a low
concurrency limit. This should improve the performance of
retrieving historical information.
2015-04-21 14:00:54 -07:00
Vinnie Falco
837b0799ac Set version to 0.28.0-rc3 2015-04-21 13:48:39 -07:00
Nik Bougalis
bc85a8b24f Set TX processing change date to 2015-05-12 13:00:00PDT 2015-04-21 13:48:38 -07:00
Miguel Portilla
15d68649d5 Fix check for current ledger ID in RPC 2015-04-21 13:48:30 -07:00
Tom Ritchford
e0d96ae807 Fix WebSockets treatment of ping timer:
This solves a problem that caused a hang on shutdown related to
the lifetime of the ping timer completion handlers used in WebSockets.

* Turn the ping timer back on
* Use std::weak_ptr for WebSockets timer callbacks.
* Disable WebSocket pings if frequency in the .cfg is non-positive.
2015-04-21 12:26:11 -07:00
Torrie Fischer
3aa39ced60 Fix circleci 2015-04-21 12:23:23 -07:00
seelabs
1f1c0618e1 Tidy up SQLite table creation:
* Check if tables and indexes exist
* Remove commands for unused table
2015-04-21 12:21:27 -07:00
seelabs
7788aa25b5 Fix return value when looking up non existent transactions 2015-04-21 12:20:53 -07:00
JoelKatz
d5b460a85c Give ledger data requests their own job type:
This gives requests for ledger data (and transaction set data)
from peers a separate job type and prioritizes it appropriately.
Previously it was lumped in with fetch packs which have a low
concurrency limit. This should improve the performance of
retrieving historical information.
2015-04-21 12:15:59 -07:00
Vinnie Falco
9019f3a4f2 Set version to 0.28.1-b2 2015-04-20 15:57:02 -07:00
seelabs
dfda0d566a Support for boost 1.58 2015-04-20 15:55:48 -07:00
Vinnie Falco
99c2fac143 STVar: optimized storage for STObject (RIPD-825):
This introduces the STVar container, capable of holding any STBase-derived
class and implementing a "small string" optimization. STObject is changed
to store std::vector<STVar> instead of boost::ptr_vector<STBase>. This
eliminates a significant number of needless dynamic memory allocations and
deallocations during transaction processing when ledger entries are
deserialized. It comes at the expense of larger overall storage requirements
for STObject.
2015-04-20 15:54:26 -07:00
Nicholas Dudfield
4c5308da8d Update account_objects test:
* Use Request over json-rpc
* Use lodash to filter irrelevant fields from expectations
* Use LedgerState for state setup
* Test using limit and marker

Conflicts:
	test/account_objects-test.js
2015-04-20 15:54:14 -07:00
Miguel Portilla
4d0ed3d857 RPC account_objects (RIPD-777)
General RPC command that can retrieve objects in the account root.
  * Add account objects integration test.
  * Support tickets.

* Add removeElement in Json::Value
2015-04-20 15:54:09 -07:00
Vinnie Falco
0b5582ed0d Disable redundant ping timer 2015-04-20 15:52:38 -07:00
Tom Ritchford
17734f833c Revert "Checkpoint SOCI exactly every 1000 pages."
This reverts commit e874a2624f.
2015-04-20 15:52:33 -07:00
Vinnie Falco
98a9d5d424 Lower the severity of some PeerFinder logging 2015-04-20 15:52:29 -07:00
Vinnie Falco
6d74f36449 Fix Crawl handshake header parsing in Overlay 2015-04-20 15:52:20 -07:00
Vinnie Falco
47a5bf6aa5 Fix beast::ci_equal 2015-04-20 15:52:16 -07:00
Vinnie Falco
2805e9eb3b Set version to 0.28.0-rc2 2015-04-20 15:19:07 -07:00
Vinnie Falco
72a1a86886 Disable redundant ping timer 2015-04-20 13:42:00 -07:00
Tom Ritchford
ec190bae33 Revert "Checkpoint SOCI exactly every 1000 pages."
This reverts commit e874a2624f.
2015-04-20 11:01:23 -07:00
Vinnie Falco
83003e43d7 Lower the severity of some PeerFinder logging 2015-04-20 11:01:20 -07:00
Vinnie Falco
3b20dc2994 Fix Crawl handshake header parsing in Overlay 2015-04-20 11:00:03 -07:00
Vinnie Falco
a7198298e7 Fix beast::ci_equal 2015-04-20 10:59:58 -07:00
Vinnie Falco
f3d76d5780 Set version to 0.28.1-b1 2015-04-17 11:43:51 -07:00
Vinnie Falco
e2305c3c5e Merge branch 'release' into develop
Conflicts:
	Builds/rpm/rippled.spec
	src/ripple/protocol/impl/BuildInfo.cpp
2015-04-17 11:43:09 -07:00
Vinnie Falco
ba737d7e58 Set version to 0.28.0-rc1 2015-04-17 11:41:50 -07:00
Vinnie Falco
88f69204c8 Merge 0.28.0-b21 into release 2015-04-17 11:41:17 -07:00
Vinnie Falco
bb4561c2b8 Set version to 0.28.0-b22 2015-04-16 11:31:57 -07:00
seelabs
4710f764e4 Quiet unused variable warning 2015-04-16 11:31:57 -07:00
JoelKatz
11a59a767e Adjust cache parameters for 'huge' node size 2015-04-16 11:31:54 -07:00
Miguel Portilla
4cf3157aad Set version to 0.28.0-b21 2015-04-14 18:54:31 -04:00
Miguel Portilla
b1f6cb349b Improved parsing of universal port configuration settings (RIPD-856) 2015-04-14 18:51:53 -04:00
David Schwartz
0c134582ca Track peer "sanity" (RIPD-836)
* Each peer has a "sane/insane/unknown" status
* Status updated based on peer ledger sequence
* Status reported in peer json
* Only sane peers preferred for historical ledgers
* Overlay endpoints only accepted from known sane peers
* Untrusted proposals not relayed from insane peers
* Untrusted validations not relayed from insane peers
* Transactions from insane peers are not processed
* Periodically drop outbound connections to bad peers
* Bad peers get bootcache valence of zero

Peer "sanity" is based on the ledger sequence number they are on.  We
quickly become able to assess this based on current trusted validations.
We quarrantine rogue messages and disconnect bad outbound connections to
help maintain the configured number of good outbound connections.
2015-04-14 18:51:52 -04:00
Nik Bougalis
acf2833362 Set version to 0.28.0-b20 2015-04-13 10:24:47 -07:00
Nik Bougalis
20f9971096 Finalize date for switchover to 0.28.0 processing semantics 2015-04-13 10:24:47 -07:00
Nik Bougalis
cefeaceef0 Signal error for incorrect configuration during unit test 2015-04-13 10:24:47 -07:00
Howard Hinnant
1ba7c4b6ee Remove unneeded member initializer:
* This works around a clang bug.
* Also un-commented correctly deleted copy members.
2015-04-13 10:24:47 -07:00
Vinnie Falco
1b49776819 Add fetchBatch Backend interface 2015-04-10 19:14:57 -07:00
Vinnie Falco
41c68f4bbc Use static_initializer in KnownFormats singleton 2015-04-10 19:14:57 -07:00
Nik Bougalis
56ac830405 Refund owner's ticket reserve when a ticket is canceled (RIPD-855) 2015-04-10 19:12:51 -07:00
Nik Bougalis
ebcf821d81 Return descriptive error from account_currencies RPC (RIPD-806):
The 'account_index' field is expected to be an integer. If something
else is specified, the error message should clearly indicate which
field is at fault.
2015-04-10 19:11:28 -07:00
Tom Ritchford
e874a2624f Checkpoint SOCI exactly every 1000 pages. 2015-04-10 19:11:28 -07:00
Tom Ritchford
03d1c0ed21 Clean SOCI code.
* Throw exception rather than SEGV.
* Hide details of checkpointing from clients.
* Restrict to 80 columns and minor style tweaks.
2015-04-10 19:11:28 -07:00
Tom Ritchford
1b8c77eee0 Allow logging to be used outside the ripple namespace.
* Split logging macros over multiple lines.
* Restrict Log.h to 80 columns.
2015-04-10 19:11:28 -07:00
Tom Ritchford
d575cd50b1 Clean up Sustain.h and Sustain.cpp.
* Bring out magic numbers.
  * Get rid of boost::format.
2015-04-10 19:11:28 -07:00
Tom Ritchford
2b040569e7 Remove deprecated flags --rpc_ip and --rpc_port. 2015-04-10 19:11:28 -07:00
Miguel Portilla
7a53f86fff Compare current seq vs validated (RIPD-669) 2015-04-10 19:11:28 -07:00
Torrie Fischer
a90bb53cd2 Drop nexmo SMS support. Reverts 58b3cc1d. 2015-04-10 19:11:27 -07:00
Tom Ritchford
b450d62138 Port to Python: Build and run tests for multiple build configurations. 2015-04-10 19:11:27 -07:00
Nik Bougalis
1a9d65c52a Set version to 0.28.0-b19 2015-04-10 19:00:45 -07:00
seelabs
05f4746bbe Add workaround include for Windows.h NOMINMAX 2015-04-10 19:00:45 -07:00
seelabs
1c587723fa Safer macro restoration using MSVC extensions 2015-04-10 19:00:34 -07:00
Nik Bougalis
b2a9c79de5 Fix transaction enumeration in account_tx (RIPD-734):
In some corner cases, an incorrect resume marker could be
returned, preventing the complete enumeration of account
transactions.

* Robust markers via improved paging support
* New unit tests
* Cleanup
2015-04-10 19:00:22 -07:00
Nik Bougalis
64259c7bcb Better transaction analysis (RIPD-755):
The analysis of differences between locally built ledgers and consensus
ledgers is now more intelligent. Differences in these values will be
categorized:

 - Operation results
 - Transaction ordering
 - Generated metadata
2015-04-10 18:58:52 -07:00
Nik Bougalis
a7efdb4e52 Improve version switchover semantics:
* Support PreviousTxnID until the switchover
* Implement "No Ripple" for issue_iou and redeem_iou.
* Do not utilize issue_iou and redeem_iou from legacy code
* Rename 0.27.x legacy files to account for VS build process
* Misc. cleanups
2015-04-10 18:56:52 -07:00
Tom Ritchford
091ff0cce0 Set version to 0.28.0-b18 2015-03-31 21:50:45 -04:00
seelabs
7e25a3a942 Fix SQL in online delete cleanup:
* SQL statement is corrected to perform an implicit JOIN
* Add unit test
2015-03-31 21:50:45 -04:00
Nik Bougalis
b3254e2b18 Remove unsupported proof-of-work command parsing 2015-03-31 21:50:44 -04:00
JoelKatz
9a0fa79144 Fix duplication of full below cache and tree node cache 2015-03-31 21:50:43 -04:00
JoelKatz
352db260b2 STArray optimization 2015-03-31 21:50:43 -04:00
Nik Bougalis
f072b5b679 Avoid copying and improve optimization opportunities 2015-03-31 21:50:43 -04:00
JoelKatz
b4058a813b Small changes to improve transaction benchmarking:
* Set transaction valid in hash router correctly
* Properly account for root nodes in walkLedger
* If loaded ledger is insane, log details
* Extra logging while loading replay ledger
* Don't test unsigned transactions expecting them to succeed
* Don't be too noisy about signature failures
2015-03-31 21:50:42 -04:00
Vinnie Falco
b27e152ead NuDB: Enforce pool_thresh minimum of 1:
pool_thresh is prevented from going to zero. This solves a problem when
using callgrind where the CPU is monopolized, causing operations that
should complete quickly to take days.
2015-03-31 21:50:42 -04:00
Tom Ritchford
936e83759d Remove three warnings. 2015-03-31 21:50:41 -04:00
Tom Ritchford
18fdc175c6 Clean structure of RPC::addPaymentDeliveredAmount 2015-03-31 21:50:41 -04:00
JoelKatz
47c6ab0ced Reduce SHAMapTreeNode copying during SHAMap unsharing:
In some code paths, we bump the SHAMap sequence number
before we unshare. This forces SHAMapTreeNode to be
copied. By making the ledger immutable we cause the
unsharing to occur earlier, eliminating the copies.
2015-03-31 21:50:40 -04:00
seelabs
4868135d47 Improve build times:
* Get classic & unity sources once only
* Use MD5-Timestamp
* Use implicit cache for specific debug builds
* Skip prep work for targets what will not be built
2015-03-31 21:50:39 -04:00
Miguel Portilla
5e70db651d Improved local tx error messages (RIPD-720)
Failed local built transactions report the specific error.
2015-03-31 21:50:39 -04:00
David Schwartz
1fedede771 Remove transaction set acquire logic from consensus object
This creates a new InboundTransactions object that handles transaction sets,
removing this responsibility from the consensus object. The main benefit is
that many inbound transaction operations no longer require the master lock.

Improve logic to decide which peers to query, when to add more peers, and
when to re-query existing peers.
2015-03-31 21:50:38 -04:00
seelabs
00596f1436 Reduce memory allocation, remove some functions in Serializer. 2015-03-31 21:50:37 -04:00
Nik Bougalis
db840b5604 Perform Transactor checks early (RIPD-751):
Certain checks that determine if a transaction is malformed can be performed
without needing to look up accounts or access the ledger.

Perform those checks as early as possible to optimize transaction processing.
2015-03-31 06:49:53 -07:00
Nik Bougalis
45070d0e51 Reduce Transaction public interface 2015-03-30 13:05:42 -07:00
Tom Ritchford
8a1081f9ef Set version to 0.28.0-b17 2015-03-26 12:38:33 -04:00
seelabs
ac84e44161 Correct missing semicolons on sql statements 2015-03-26 12:38:33 -04:00
seelabs
836dfb6503 Do not log errors from initial database statements 2015-03-26 12:38:33 -04:00
Edward Hennis
35a8ce2349 Pathfinding unit tests:
* Refactor ripple path find to be more testable.
* Reimplements the first 4 tests from `tests\path-test.js`
* Verify balances in Ledger test.
2015-03-26 12:38:33 -04:00
Tom Ritchford
bb7d68b3b9 Add notes about Rippled's container classes. 2015-03-26 12:38:33 -04:00
Howard Hinnant
1979846e5e Change several uses of std::list to alternative containers:
*  Performance motivated.
*  Several of these called size() which is O(N) in gcc-4.8.
*  Remove container copy from LedgerConsensusImp::playbackProposals().
*  Addresses RIPD-284.
2015-03-26 12:38:33 -04:00
Howard Hinnant
a61ffab3f9 Remove unnecessary allocation/deallocation from masterLock
* Add make_lock.
* Rename Application::LockType to Application::MutexType:
* Rename getMasterLock to getMasterMutex.
* Use getMasterMutex and make_lock.
* Remove unused code.
2015-03-26 12:38:33 -04:00
Howard Hinnant
698fe73608 Move SHAMap hash computations from dirtyUp to walkSubTree
in order to reduce the total number of hash computations.
2015-03-26 12:38:33 -04:00
Josh Juran
0083c32629 Update VS project files 2015-03-26 12:38:33 -04:00
Nik Bougalis
f313caaa73 Set version to 0.28.0-b16 2015-03-19 07:55:19 -07:00
Edward Hennis
6e3f07ddce Remove unused / redundant functions. 2015-03-19 07:41:57 -07:00
Mark Travis
11d28c4856 Always increment payment pass counter 2015-03-19 07:41:57 -07:00
Nik Bougalis
e9394ca85a Implement "Default Ripple" logic in active direction:
When a balance change invokes trustCreate, we need to set the no ripple flag
if the "active" account's asfRippleDefault flag is cleared.
2015-03-19 07:41:57 -07:00
Nik Bougalis
9445a30e72 Implement "Default Ripple" logic in LedgerEntrySet::checkState 2015-03-19 07:41:57 -07:00
JoelKatz
185b1a3d36 Add noripple_check RPC command
To help gateways make the changes needed to adjust to the
"default ripple" flag, we've added the "noripple_check"
RPC command. This command tells gateways what they need
to do to set this flag and fix any trust lines created
before they set the flag.

Once your server is running and synchronized, you can run
the tool from the command line with a command like:
  rippled json noripple_check '
  {
    "account" : "<gateway_trusted_address_here>",
    "role" : "gateway",
    "transactions" : "true"
  }'

The server will respond with a list of "problems" that it
sees with the configuration of the account and its trust
lines. It will also return a "transactions" array suggesting
the transactions needed to fix the problems it found.
2015-03-19 07:41:57 -07:00
JoelKatz
1c2f5d60a5 Subscribe/Unsubscribe improvements:
* Don't acquire the master lock where it's not needed
* InfoSub tracks RT and validated accounts separately
* Correctly remove accounts from the InfoSub
2015-03-19 07:41:57 -07:00
JoelKatz
2f32910bef Reduce master lock scope in some RPC functions 2015-03-19 07:41:57 -07:00
JoelKatz
8de1b20bb5 Defer/avoid acquiring the master lock on proposals 2015-03-19 07:41:57 -07:00
David Schwartz
60a7abcef6 Decongest the master lock:
* Reduce scope of lock in ledger accept
* Remove duplicate tracking of transaction sets
* Need master lock to secure ledger sequencing
2015-03-19 07:41:57 -07:00
David Schwartz
e44e75fa6b Track and report peer load:
* PeerImp::charge only calls fail if dispatched from the peer
* Add "load" to output of RPC command "peer"
* Add Resource::Charge values for peer commands
* Impose some fee for every peer command
* Cleanup fee imposition
2015-03-19 07:41:57 -07:00
JoelKatz
ff7dc0b446 Reduce chatty log outputs 2015-03-19 07:41:57 -07:00
JoelKatz
f813cb2310 Tolerate LedgerSequence field in pseudo-transactions:
This will enable a forthcoming change to prevent pseudo-transactions
from reusing a transaction ID
2015-03-19 07:41:57 -07:00
JoelKatz
cba19d7e23 Document and cleanup ledger advance logic
* Don't acquire if validated ledger is old
* Don't try to publish if no valid ledger
* Update README.md file
2015-03-19 07:41:57 -07:00
Nicholas Dudfield
9479c0e12d Update uniport tests to use new config 2015-03-18 19:39:30 -07:00
Nicholas Dudfield
65c9c45ec6 Rename test file so npm test finds it 2015-03-18 19:39:30 -07:00
Miguel Portilla
6d79004d4f Better admin IP management in .cfg (RIPD-820):
* Deprecate rpc_admin_allow section from configuration file
* New port-specific setting 'admin':
  * Comma-separated list of IP addresses that are allowed administrative
    privileges (subject to username & password authentication if configured)
  * 127.0.0.1 is no longer a default admin IP.
  * 0.0.0.0 may be specified to indicate "any IP" but cannot be combined
    with other IP addresses.
2015-03-18 19:39:30 -07:00
seelabs
97623d20c5 Use soci in more places:
* Validator, peerfinder, SHAMapStore,
  RpcDB, TxnDB, LedgerDB, WalletDB use soci backend.
2015-03-18 19:39:26 -07:00
seelabs
d37802a42f Remove SqliteFactory. 2015-03-18 19:37:09 -07:00
seelabs
9b837a24aa Remove beast's sqdb module.
Conflicts:
	src/beast/beast/module/sqdb/api/backend.h
	src/beast/beast/module/sqdb/api/blob.h
	src/beast/beast/module/sqdb/api/into.h
	src/beast/beast/module/sqdb/api/session.h
	src/beast/beast/module/sqdb/api/statement.h
	src/beast/beast/module/sqdb/api/transaction.h
	src/beast/beast/module/sqdb/api/type_conversion_traits.h
	src/beast/beast/module/sqdb/api/use.h
	src/beast/beast/module/sqdb/detail/error_codes.h
	src/beast/beast/module/sqdb/detail/exchange_traits.h
	src/beast/beast/module/sqdb/detail/into_type.h
	src/beast/beast/module/sqdb/detail/once_temp_type.h
	src/beast/beast/module/sqdb/detail/prepare_temp_type.h
	src/beast/beast/module/sqdb/detail/ref_counted_prepare_info.h
	src/beast/beast/module/sqdb/detail/ref_counted_statement.h
	src/beast/beast/module/sqdb/detail/statement_imp.h
	src/beast/beast/module/sqdb/detail/type_conversion.h
	src/beast/beast/module/sqdb/detail/type_ptr.h
	src/beast/beast/module/sqdb/detail/use_type.h
	src/beast/beast/module/sqdb/sqdb.h
2015-03-18 19:37:08 -07:00
seelabs
d0ef2f7dd8 Use soci in some places:
* Brings the soci subtree into rippled.
* Validator, peerfinder, and SHAMapStore use new soci backend.
* Optional postgresql backend for soci (if POSTGRESQL_ROOT env var is set).
2015-03-18 19:37:08 -07:00
seelabs
c7cfd23580 Update sqlite3 to 3.8.8.2. 2015-03-18 19:37:03 -07:00
Vinnie Falco
7cf1ec3f89 Merge commit '9708a1260720d879d76a10f894925962f20611bc' as 'src/soci' 2015-03-18 19:36:00 -07:00
Vinnie Falco
9708a12607 Squashed 'src/soci/' content from commit 6e9312c
git-subtree-dir: src/soci
git-subtree-split: 6e9312c4bb3748907bd28d62c40feca42878cfef
2015-03-18 19:36:00 -07:00
Nik Bougalis
92812fe723 Set version to 0.27.4 2015-03-18 17:54:57 -07:00
JoelKatz
79417ac59a Limit passes in the payment engine to prevent endless looping:
This adds a limit of 1,000 passes to the payment engine. It protects against
possible cases where the execution of a pass fails to exhaust the liquidity
that made the pass possible or cases where two passes alternate providing
liquidity for each other.
2015-03-18 17:53:52 -07:00
Mark Travis
984f66e083 Don't VACUUM SQLite databases on startup with online delete enabled. 2015-03-18 17:53:42 -07:00
Tom Ritchford
ef2a436769 Set version to 0.28.0-b15 2015-03-16 20:54:17 -04:00
Edward Hennis
7f1a95550f Clean up unit test logs on success.
* Add a little bit of shell variable safety and tweak output.
2015-03-16 20:54:17 -04:00
seelabs
803f5b5613 Use buffer in STBlob 2015-03-16 20:54:15 -04:00
Nicholas Dudfield
8ca9fa1c26 Fix testutils.create_accounts
* Don't call ledger_wait inside parallel async loop
2015-03-16 20:54:14 -04:00
David Schwartz
3b3b897193 Add "Default Ripple" account flag and associated logic:
AccountSet set/clear, asfDefaultRipple = 8

AccountRoot flag, lsfDefaultRipple = 0x00800000

In trustCreate, set no ripple flag if appropriate.

If an account does not have the default ripple flag set,
new ripple lines created as a result of its offers being
taken or people creating trust lines to it have no ripple
set by that account's side automatically

Trust lines can be deleted if the no ripple flag matches
its default setting based on the account's default ripple
setting.

Fix default no-rippling in integration tests.
2015-03-16 20:54:14 -04:00
Torrie Fischer
6c364f63cc Build docker images on circleci based on travis.yml 2015-03-16 20:54:14 -04:00
seelabs
6b9e842ddd Replaces StringPairArray with Section in Config. 2015-03-16 20:54:13 -04:00
Nik Bougalis
8f88d915ba Support switchover from 0.27 to 0.28 processing semantics based on time:
Changes made to support autobridging and improve the offer-crossing and
pathfinding logic result in transaction-breaking changes which cause
incompatibilities between 0.27 and 0.28 builds of RippleD.

This patch simplifies deployment of 0.28 on the Ripple network by allowing
RippleD to emulate the 0.27 semantics while the last closed ledger closed
before March 30, 2015 at 13:00:00 PDT, after which time the new 0.28
semantics will become active.

The transaction-breaking changes addressed in this commit are:
    3ccbd7c9b2
    b203db27a4
2015-03-16 20:54:12 -04:00
JoelKatz
eaa1f47f00 Limit passes in the payment engine to prevent endless looping:
This adds a limit of 1,000 passes to the payment engine. It protects against
possible cases where the execution of a pass fails to exhaust the liquidity
that made the pass possible or cases where two passes alternate providing
liquidity for each other.
2015-03-16 20:54:11 -04:00
JoelKatz
cbeae85731 Fix specified destination issuer in pathfinding (RIPD-812)
* Compute the effective recipient.
* Make sure the effective recipient exists.
* Prohibit paths to the recipient, if not the effective recipient.
* Treat paths to the effective recipient as complete.
* Don't find looped paths.
* Use the effective recipient for getPathsOut weight.
2015-03-16 20:54:09 -04:00
Nik Bougalis
84e618b3f2 Improve pool seeding during startup:
* When starting up, we no longer rely just on the standard
  system RNG to generate entropy: we attempt to squeeze some
  from the execution state, and to recover any entropy that
  we had previously stored.

* When shutting down, if sufficient entropy has been accumulated
  attempt to store it for future use.
2015-03-16 20:54:08 -04:00
JoelKatz
382a16ff07 Avoid excess ledger header requests 2015-03-16 20:54:07 -04:00
JoelKatz
7bd339b645 Balance peer selection in getFetchPack 2015-03-16 20:54:07 -04:00
David Schwartz
70d8b2c4b7 getMissingNode performance and logging improvements 2015-03-16 20:54:07 -04:00
David Schwartz
3764a83c6b Ledger binary option
Conflicts:
	src/ripple/app/ledger/Ledger.cpp
	src/ripple/app/ledger/Ledger.h
	src/ripple/rpc/handlers/Ledger.cpp
2015-03-16 20:54:06 -04:00
Tom Ritchford
c3d200ddcd Set version to 0.28.0-b14 2015-03-13 11:21:02 -04:00
Tom Ritchford
44c5e337ab Remove obsolete comments from doc/CHANGELOG. 2015-03-13 11:21:02 -04:00
Nik Bougalis
040982e321 Only report 'delivered_amount' for executed payments (RIPD-827) 2015-03-13 11:21:00 -04:00
Nik Bougalis
6c81ea846c Calculate deep offer quality 2015-03-13 11:20:59 -04:00
Josh Juran
d082a0696d Support Ed25519 keys and signatures:
Recognize a new JSON parameter `key_type` in handlers for wallet_propose
and sign/submit.  In addition to letting the caller to specify either of
secp256k1 or ed25519, its presence prohibits the (now-deprecated) use of
heuristically polymorphic parameters for secret data -- the `passphrase`
parameter to wallet_propose will be not be considered as an encoded seed
value (for which `seed` and `seed_hex` should be used), and the `secret`
parameter to sign and submit will be obsoleted entirely by the same trio
above.

* Use constants instead of literals for JSON parameter names.
* Move KeyType to its own unit and add string conversions.
* RippleAddress
  * Pass the entire message, rather than a hash, to accountPrivateSign()
    and accountPublicVerify().
  * Recognize a 33-byte value beginning with 0xED as an Ed25519 key when
    signing and verifying (for accounts only).
  * Add keyFromSeed() to generate an Ed25519 secret key from a seed.
  * Add getSeedFromRPC() to extract the seed from JSON parameters for an
    RPC call.
  * Add generateKeysFromSeed() to produce a key pair of either type from
    a seed.
* Extend Ledger tests to cover both key types.
2015-03-12 21:53:59 -07:00
Nik Bougalis
f999839e59 Set version to 0.27.3-sp2 2015-03-12 13:37:47 -07:00
JoelKatz
f1bc662a24 Add noripple_check RPC command
To help gateways make the changes needed to adjust to the
"default ripple" flag, we've added the "noripple_check"
RPC command. This command tells gateways what they need
to do to set this flag and fix any trust lines created
before they set the flag.

Once your server is running and synchronized, you can run
the tool from the command line with a command like:
  rippled json noripple_check '
  {
    "account" : "<gateway_trusted_address_here>",
    "role" : "gateway",
    "transactions" : "true"
  }'

The server will respond with a list of "problems" that it
sees with the configuration of the account and its trust
lines. It will also return a "transactions" array suggesting
the transactions needed to fix the problems it found.
2015-03-12 13:37:06 -07:00
Nik Bougalis
232693419a Set version to 0.27.3-sp1 2015-03-11 10:26:39 -07:00
Nicholas Dudfield
ed66b951c6 Fix testutils.create_accounts
* Don't call ledger_wait inside parallel async loop
2015-03-11 10:25:27 -07:00
Nik Bougalis
70c2854f7c Set version to 0.27.3 2015-03-10 14:06:33 -07:00
David Schwartz
e9381ddeb2 Add "Default Ripple" account flag and associated logic:
AccountSet set/clear, asfDefaultRipple = 8

AccountRoot flag, lsfDefaultRipple = 0x00800000

In trustCreate, set no ripple flag if appropriate.

If an account does not have the default ripple flag set,
new ripple lines created as a result of its offers being
taken or people creating trust lines to it have no ripple
set by that account's side automatically

Trust lines can be deleted if the no ripple flag matches
its default setting based on the account's default ripple
setting.

Fix default no-rippling in integration tests.
2015-03-10 14:05:18 -07:00
Tom Ritchford
1b46e003c3 Set version to 0.28.0-b13 2015-03-09 17:49:39 -04:00
Howard Hinnant
4611d5a35f Remove unused SyncUnorderedMap 2015-03-09 17:49:39 -04:00
Nicholas Dudfield
2e59378ab7 Fix AppVeyor:
* Detect continuous integration environment via `CI` variable
* Use double quotes for build cache path
2015-03-09 17:49:39 -04:00
JoelKatz
fc8bf39043 Simplify tracking of recently requested ledger entries
Instead of tracking recently-requested entries from inbound
ledgers by node ID, track by hash. This allows state and
transaction entries to be tracked in the same set.
2015-03-09 17:49:38 -04:00
Vinnie Falco
2cccd8ab28 Fix gentex usage in nudb 2015-03-09 17:49:37 -04:00
Vinnie Falco
d537ceedd6 Tidy up nudb:
* Define WIN32_LEAN_AND_MEAN before including Windows.h
* Remove unnecessary template argument
* Rename to identity
* Make identity default api codec
2015-03-09 17:49:37 -04:00
Tom Ritchford
ac7243b309 Remove unused static function. 2015-03-02 17:40:12 -05:00
Tom Ritchford
607e983f37 Set version to 0.28.0-b12 2015-03-02 16:50:01 -05:00
Mark Travis
02f7326b7e Remove orphan function. 2015-03-02 16:50:01 -05:00
Edward Hennis
b688f69031 Builds/test-only.sh will build and test by scons target.
* test-all.sh simplified to call test-only.sh.
* Script fails if build or tests fail. Allows chaining and git bisect run.
* Add copyright notice
* Ignore gprof performance data created by testing the profile builds.
2015-03-02 16:50:00 -05:00
Tom Ritchford
df41329df9 Replace "it's" with "its" in several places. 2015-03-02 16:49:59 -05:00
Tom Ritchford
0825bd7076 Cleanups to Json Object code.
* Replace Json::JsonException with std::logic_error.
* Move two functions definitions to Object.cpp.
* Fix include guards.
2015-03-02 16:49:56 -05:00
Tom Ritchford
e9b7003cf5 Move streaming Json objects to ripple/json. 2015-03-02 16:49:56 -05:00
Tom Ritchford
c5d673c426 Better integration between JsonObject and Json::Value. 2015-03-02 16:49:56 -05:00
Nik Bougalis
9cc8eec773 Set version to 0.27.2 2015-03-01 14:56:44 -08:00
Nik Bougalis
0b45535061 Calculate deep offer quality 2015-02-28 13:28:54 -08:00
Tom Ritchford
9f64ad8d89 Add WebSocket 04 interface.
* New WebSocket04 traits class implements strategies.
* New "websocket_version" configuration setting selects between 0.2 and 0.4.
2015-02-28 14:57:38 -05:00
Tom Ritchford
e5b0b7e9a7 Expose a method and add a handler in websocketpp.
* Expose websocketpp::transport::asio::connection::get_strand().
* Add new send_empty_handler to websocketpp::endpoint.
2015-02-28 14:57:38 -05:00
Tom Ritchford
9c3522cb70 Isolate WebSocket 0.2-specific code.
* Hide implementation details of the WebSocket server from clients.
* Extract a generic traits class.
2015-02-28 14:57:38 -05:00
Tom Ritchford
b357390215 Remove redundant post to strand in websocket. 2015-02-27 12:11:54 -05:00
Tom Ritchford
c66fc2f656 Rename all WebSocket code into one directory. 2015-02-27 12:11:54 -05:00
Tom Ritchford
64554aca6d Set version to 0.28.0-b11 2015-02-26 21:02:39 -05:00
Nik Bougalis
f1df9a02fa Fix declaration/implementation mismatches 2015-02-26 21:02:38 -05:00
JoelKatz
f3725bdd2e Return a validated ledger if there is one (RIPD-814)
LedgerMaster::getLedgerBySeq should return a validated
ledger (rather than the the open or closed ledger) for
a sequence number for which it has a fully-validated ledger.
2015-02-26 21:02:37 -05:00
Tom Ritchford
cb92b94d55 Remove unused variable. 2015-02-26 21:02:36 -05:00
Vinnie Falco
ef01f82e0c Add nounity targets to msvc projects 2015-02-26 21:02:35 -05:00
Vinnie Falco
4ba7ee8c92 Support per-target ExcludeFromBuild in VSProject 2015-02-26 21:02:35 -05:00
Howard Hinnant
c59633a588 Make SHAMap::fetchNodeFromDB const
When fetchNodeFromDB discovers a missing node in the database it
must reset the ledger sequence to 0.  By treating this as a logically
const operation, even though not physically const, many other member
functions can be made const, including compare.
2015-02-26 21:02:33 -05:00
Vinnie Falco
f56e37398c Always use HTTP handshaking in overlay:
Inbound and outbound peer connections always use HTTP handshakes to
negotiate connections, instead of the deprecated TMHello protocol
message.

rippled versions 0.27.0 and later support both optional HTTP handshakes
and legacy TMHello messages, so always using HTTP handshakes should not
cause disruption. However, versions before 0.27.0 will no longer be
able to participate in the overlay network - support for handshaking
via the TMHello message is removed.
2015-02-26 21:02:32 -05:00
Tom Ritchford
e43ffa6f2b Set version to 0.28.0-b10 2015-02-25 20:26:12 -05:00
Yana
6991bc9723 Spelling corrections 2015-02-25 20:26:12 -05:00
Miguel Portilla
9d6106a80b Require boost 1.57 2015-02-25 20:26:12 -05:00
Tom Ritchford
9e70404411 Get rid of compilation warning. 2015-02-25 20:26:12 -05:00
Nik Bougalis
bc48d299b6 Report server versions when crawling the overlay network 2015-02-25 20:26:12 -05:00
mDuo13
a8db5650a5 Add online_delete reminder to ledger_history in example cfg 2015-02-25 19:56:47 -05:00
Nicholas Dudfield
91871b418b Changes to Universal Port:
* Add tests
* Introduce requestRole helper
* Always honor admin=no
* Welcome guests anywhere admin privileges aren't required
2015-02-25 19:46:56 -05:00
Tom Ritchford
aaf98082e9 Set version to 0.28.0-b9 2015-02-24 20:28:43 -05:00
Tom Ritchford
ac228deeda Replace LEDGER_JSON_ macros with an enum. 2015-02-24 20:28:43 -05:00
Edward Hennis
fc661c83ef Build and run tests on all available build types
* Tests include unit and integration (npm)
2015-02-24 20:28:43 -05:00
Vinnie Falco
a2acffdfa3 New serialized object, public key, and private key interfaces
This introduces functions get and set, and a family of specialized
structs called STExchange. These interfaces allow efficient and
seamless interchange between serialized object fields and user
defined types, especially variable length objects.

A new base class template TypedField is mixed into existing SField
declarations to encode information on the field, allowing template
metaprograms to both customize interchange based on the type and
detect misuse at compile-time.

New types AnyPublicKey and AnySecretKey are introduced. These are
intended to replace the corresponding functionality in the deprecated
class RippleAddress. Specializations of STExchange for these types
are provided to allow interchange. New free functions verify and sign
allow signature verification and signature generation for serialized
objects.

* Add Buffer and Slice primitives
* Add TypedField and modify some SField
* Add STExchange and specializations for STBlob and STInteger
* Improve STBlob and STInteger to support STExchange
* Expose raw data in RippleAddress and Serializer
2015-02-24 20:28:43 -05:00
David Schwartz
79ce4ed226 Document cluster configuration and monitoring (RIPD-732) 2015-02-24 20:28:43 -05:00
Nik Bougalis
e3a7aa0033 Constrain valid inputs for memo fields (RIPD-712) 2015-02-24 20:25:34 -05:00
Vinnie Falco
95973ba3e8 Set version to 0.27.1 2015-02-24 13:31:13 -08:00
Tom Ritchford
fde6303ae6 Set version to 0.28.0-b8 2015-02-24 12:33:59 -05:00
Vinnie Falco
b4a1948951 Use all parts of suite name to detect duplicates 2015-02-24 12:33:59 -05:00
Miguel Portilla
b927028416 Display human readable SSL error codes 2015-02-24 12:33:59 -05:00
Tom Ritchford
fe5d1ff6c5 Set version to 0.28.0-b7 2015-02-23 11:53:21 -08:00
Yana
1308656000 Update README.md file (RIPD-802) 2015-02-23 11:53:20 -08:00
Howard Hinnant
ec1e6b9385 Cleanup and simplifications to SHAMap:
SHAMapTreeNode
* Remove SHAMapTreeNode::pointer and SHAMapTreeNode::ref.
* Add std includes necessary to make the header standalone.
* Remove implementation from the SHAMapTreeNode declaration.
* Make clear what part of SHAMapTreeNode is:
  1) Truly public.
  2) Used only by SHAMap.
  3) Truly private to SHAMapTreeNode.

SHAMapItem
* Remove SHAMapItem::pointer and SHAMapItem::ref.
* Add std includes necessary to make the header standalone.
* Remove implementation from the SHAMapItem declaration.
* Make clear what part of SHAMapItem is:
  1) Truly public.
  2) Used only by SHAMapTreeNode.
  3) Truly private to SHAMapItem.

SHAMapSyncFilter
* Add override for SHAMapSyncFilter-derived functions.
* Add missing header.
* Default the destructor and delete the SHAMapSyncFilter copy members.

SHAMapNodeID
* Remove unused mHash member.
* Remove unused std::hash and boost::hash specializations.
* Remove unused constructor.
* Remove unused comparison with uint256.
* Remove unused getNodeID (int depth, uint256 const& hash).
* Remove virtual specifier from getString().
* Fix operator<= and operator>=.
* Document what API is used outside of SHAMap.
* Move inline definitions outside of the class declaration.

SHAMapMissingNode
* Make SHAMapType a enum class to prevent unwanted conversions.
* Remove needless ~SHAMapMissingNode() declaration/definition.
* Add referenced std includes.

SHAMapAddNode
* Make SHAMapAddNode (int good, int bad, int duplicate) ctor private.
* Move all member function definitions out of the class declaration.
* Remove dependence on beast::lexicalCastThrow.
* Make getGood() const.
* Make get() const.
* Add #include <string>.

SHAMap
* Remove unused enum STATE_MAP_BUCKETS.
* Remove unused getCountedObjectName().
* Remove SHAMap::pointer
* Remove SHAMap::ref
* Remove unused fetchPackEntry_t.
* Remove inline member function definitions from class declaration.
* Remove unused getTrustedPath.
* Remove unused getPath.
* Remove unused visitLeavesInternal.
* Make SHAMapState an enum class.
* Explicitly delete SHAMap copy members.
* Reduce access to nested types as much as possible.
* Normalize member data names to one style.

* Change last of the typedefs to usings under shamap.
* Reorder some includes ripple-first, beast-second.
* Declare a few constructions from make_shared with auto.
* Mark those SHAMap member functions which can be, with const.

* Add missing includes
2015-02-23 11:44:57 -08:00
Tom Ritchford
315a8b6b60 Use jss for many Json fields.
* Document JsonFields.
  * Remove some unused JsonFields values.
2015-02-23 14:36:34 -05:00
Nik Bougalis
558c6b621b Clean up JSON code:
* Remove obsolete files
* Remove obsolete preprocessor configuration tags and decorations
* Remove arcane functionality (YAML compatibility, comment support)
* Enforce strict mode (single root)
* Improve parsing of numerical types
* Misc. cleanups
2015-02-23 14:36:34 -05:00
Edward Hennis
6d91d02c62 Unit test simulated ledgers can do signature verification. 2015-02-23 14:34:37 -05:00
Josh Juran
436ded68b7 Add unit tests for wallet keypair generation:
* Allow `passphrase` to be a seed encoded in any of three formats or a
    literal passphrase.
  * Recognize the absence of `passphrase` as requesting a random seed.

Extract walletPropose() and keypairForSignature() as separately factored
functions (from doWalletPropose() and transactionSign() respectively) to
facilitate unit testing.
2015-02-23 14:34:35 -05:00
JoelKatz
3ec88b3665 Implement getFetchPack using visitDifferences 2015-02-23 14:34:34 -05:00
Tom Ritchford
2caedb38a6 Set version to 0.28.0-b6 2015-02-18 13:31:31 -05:00
Vinnie Falco
49378ab7fe Fix streambuf bug:
The buffers_type::iterator could hold a pointer to a buffers_type that
was destroyed. This changes buffers_type::iterator to point to the
original streambuf instead, which always outlives the iterator.
2015-02-18 13:31:18 -05:00
Vinnie Falco
982dc6aa8c Reject invalid requests on peer port sooner. 2015-02-18 13:31:18 -05:00
Mark Travis
33175187b7 Don't VACUUM SQLite databases on startup with online delete enabled. 2015-02-18 13:31:18 -05:00
Tom Ritchford
0339904920 Update nudb comments. 2015-02-18 13:31:18 -05:00
Vinnie Falco
8bda9487c6 Add shamap::Family injection bundle 2015-02-18 13:31:18 -05:00
seelabs
617d84c0ef BasicConfig support for legacy values:
* A legacy value is a config section with a single-line.
* These values may be read from the BasicConfig interface so
  the deprecated Config class does not need to be exposed to
  clients.
* Made Config class more testable.
2015-02-18 13:31:18 -05:00
Vinnie Falco
ac64731d55 Set version to 0.27.1-rc3 2015-02-12 12:59:48 -08:00
Vinnie Falco
5dc064e971 Revert "Disable Overlay socket handoffs"
This reverts commit 8eb05d0950.
2015-02-12 12:59:48 -08:00
Vinnie Falco
c24732ed4e Fix streambuf bug:
The buffers_type::iterator could hold a pointer to a buffers_type that
was destroyed. This changes buffers_type::iterator to point to the
original streambuf instead, which always outlives the iterator.
2015-02-12 12:59:35 -08:00
Vinnie Falco
ba710bee86 Reject invalid requests on peer port sooner. 2015-02-12 12:43:42 -08:00
Vinnie Falco
c20392ca80 Set version to 0.27.1-rc2 2015-02-11 20:53:27 -08:00
Vinnie Falco
8eb05d0950 Disable Overlay socket handoffs 2015-02-11 20:53:27 -08:00
Tom Ritchford
b11ad375cd Set version to 0.28.0-b5 2015-02-11 20:42:38 -05:00
Josh Juran
7a6d533014 Refactor GenerateDeterministicKey and its call sites:
Remove the use of ec_key parameters and return values from ECDSA crypto
prototypes.  Don't store key data into an ec_key variable only to fetch
it back into the original type again.  Use uint256 and Blob explicitly.

Pass private keys as uint256, and pass public keys as either pointer and
length or Blob in calls to ECDSA{Sign,Verify}() and {en,de}cryptECIES().

Replace GenerateRootDeterministicKey() with separate functions returning
either the public or private key, since no caller needs both at once.

Simplify the use of GenerateDeterministicKey within RippleAddress.  Call
a single routine rather than pass the result of one as input to another.

Add openssl unit with RAII classes for bignum, bn_ctx, and ec_point plus
free utility functions.

Rewrite the functions in GenerateDeterministicKey.cpp to use RAII rather
than explicit cleanup code:
  * factor out secp256k1_group and secp256k1_order for reuse rather than
    computing them each time
  * replace getPublicKey() with serialize_ec_point(), which makes, sets,
    and destroys an ec_key internally (sparing the caller those details)
    and calls i2o_ECPublicKey() directly
  * return bignum rather than ec_key from GenerateRootDeterministicKey()
  * return ec_point rather than EC_KEY* from GenerateRootPubKey()

Move ECDSA{Private,Public}Key() to a new ECDSAKey unit.
Move ec_key.h into impl/ since it's no longer used outside crypto/.

Remove now-unused member functions from ec_key.

Change tabs to spaces; trim trailing whitespace (including blank lines).
2015-02-11 20:42:38 -05:00
Howard Hinnant
be44f75d2d Add missing includes. 2015-02-11 20:42:38 -05:00
Vinnie Falco
ab14123aed Remove obsolete classes:
Legacy workarounds for Visual Studio non thread-safe initialization
of function local objects with static storage duration are removed:

* Remove LeakChecked
* Remove StaticObject
* Remove SharedSingleton
2015-02-11 20:42:38 -05:00
Tom Ritchford
a963a6d10d Add noexcept qualifier to swaps and moves. 2015-02-11 20:42:38 -05:00
Vinnie Falco
69b4cd22a2 Speed up some unit tests:
A few of the slowest unit tests are modified to process a smaller data
set size, to reduce the time required to run all unit tests.
2015-02-11 20:14:44 -05:00
Vinnie Falco
958325653f Add elapsed time report for unit test runner:
When unit tests are complete, the longest running tests if any are logged.
2015-02-11 20:14:44 -05:00
Josh Juran
c5dc419f9e Remove unused source file 2015-02-11 20:14:44 -05:00
Vinnie Falco
2a201f9525 Add RocksDB to nudb import tool (RIPD-781,785):
This custom tool is specifically designed for very fast import of
RocksDB nodestore databases into NuDB.
2015-02-11 20:14:44 -05:00
Vinnie Falco
b7ba509618 NuDB: Use nodeobject codec in Backend (RIPD-793):
This adds codecs for snappy and lz4, and a new nodeobject codec. The
nodeobject codec provides a highly efficient custom compression scheme
for inner nodes, which make up the majority of nodestore databases.
Non inner node objects are compressed using lz4.

The NuDB backend is modified to use the nodeobject codec. This change
is not backward compatible - older NuDB databases cannot be opened or
imported.
2015-02-11 14:41:33 -08:00
Vinnie Falco
f946d7b447 Remove obsolete NodeObject fields:
Legacy fields of NodeObject are removed, as they are no longer
used and there is a space savings from omitting them:

* Remove LedgerIndex
2015-02-11 14:41:32 -08:00
Vinnie Falco
e2a5535ed6 NuDB: Performance improvements (RIPD-793,796):
This introduces changes in nudb to improve speed, reduce database size,
and enhance correctness. The most significant change is to store hashes
rather than entire keys in the key file. The output of the hash function
is reduced to 48 bits, and stored directly in buckets.

The API is also modified to introduce a Codec parameter allowing for
compression and decompression to be supported in the implementation
itself rather than callers.

THe data file no longer contains a salt, as the salt is applicable
only to the key and log files. This allows a data file to have multiple
key files with different salt values. To distinguish physical files
belonging to the same logical database, a new field UID is introduced.
The UID is a 64-bit random value generated once on creation and stored
in all three files.

Buckets are zero filled to the end of each block, this is a security
measure to prevent unintended contents of memory getting stored to
disk. NuDB offers the varint integer type, this is identical to
the varint described by Google.

* Add varint
* Add Codec template argument
* Add "api" convenience traits
* Store hash in buckets
* istream can throw short read errors
* Support std::uint8_t format in streams
* Make file classes part of the public interface
* Remove buffers pessimization, replace with buffer
* Consolidate creation utility functions to the same header
* Zero fill unused areas of buckets on disk
* More coverage and improvements to the recover test
* Fix file read/write to loop until all bytes processed
* Add verify_fast, faster verify for large databases

The database version number is incremented to 2; older databases can
no longer be opened and should be deleted.
2015-02-11 14:41:31 -08:00
Vinnie Falco
0f94e2c0c3 Set version to 0.27.1-rc1 2015-02-10 16:22:14 -08:00
Vinnie Falco
a25508b98d Add RocksDB to nudb import tool (RIPD-781,785):
This custom tool is specifically designed for very fast import of
RocksDB nodestore databases into NuDB.
2015-02-10 16:22:14 -08:00
Vinnie Falco
e825433a38 NuDB: Use nodeobject codec in Backend (RIPD-793):
This adds codecs for snappy and lz4, and a new nodeobject codec. The
nodeobject codec provides a highly efficient custom compression scheme
for inner nodes, which make up the majority of nodestore databases.
Non inner node objects are compressed using lz4.

The NuDB backend is modified to use the nodeobject codec. This change
is not backward compatible - older NuDB databases cannot be opened or
imported.
2015-02-10 16:22:13 -08:00
Vinnie Falco
d1c08889fe Remove obsolete NodeObject fields:
Legacy fields of NodeObject are removed, as they are no longer
used and there is a space savings from omitting them:

* Remove LedgerIndex
2015-02-10 16:22:13 -08:00
Vinnie Falco
0b82b5a0d6 NuDB: Performance improvements (RIPD-793,796):
This introduces changes in nudb to improve speed, reduce database size,
and enhance correctness. The most significant change is to store hashes
rather than entire keys in the key file. The output of the hash function
is reduced to 48 bits, and stored directly in buckets.

The API is also modified to introduce a Codec parameter allowing for
compression and decompression to be supported in the implementation
itself rather than callers.

THe data file no longer contains a salt, as the salt is applicable
only to the key and log files. This allows a data file to have multiple
key files with different salt values. To distinguish physical files
belonging to the same logical database, a new field UID is introduced.
The UID is a 64-bit random value generated once on creation and stored
in all three files.

Buckets are zero filled to the end of each block, this is a security
measure to prevent unintended contents of memory getting stored to
disk. NuDB offers the varint integer type, this is identical to
the varint described by Google.

* Add varint
* Add Codec template argument
* Add "api" convenience traits
* Store hash in buckets
* istream can throw short read errors
* Support std::uint8_t format in streams
* Make file classes part of the public interface
* Remove buffers pessimization, replace with buffer
* Consolidate creation utility functions to the same header
* Zero fill unused areas of buckets on disk
* More coverage and improvements to the recover test
* Fix file read/write to loop until all bytes processed
* Add verify_fast, faster verify for large databases

The database version number is incremented to 2; older databases can
no longer be opened and should be deleted.
2015-02-10 16:22:13 -08:00
Vinnie Falco
a33d0d4fb6 Add general delimiter split() to rfc2616 2015-02-08 19:43:37 -08:00
Vinnie Falco
ba42334d36 Add lz4
Conflicts:
	Builds/VisualStudio2013/RippleD.vcxproj
	Builds/VisualStudio2013/RippleD.vcxproj.filters
2015-02-08 19:43:26 -08:00
Vinnie Falco
2e62641aa4 Merge commit 'dad460dcfc8466a8e1c59529d490829fcfaeee73' as 'src/lz4' 2015-02-08 19:43:04 -08:00
Vinnie Falco
dad460dcfc Squashed 'src/lz4/' content from commit e25b51d
git-subtree-dir: src/lz4
git-subtree-split: e25b51de7b51101e04ceea194dd557fcc23c03ca
2015-02-08 19:43:04 -08:00
Vinnie Falco
3ae23b6a54 Remove spurious call to fetch in NuDBBackend 2015-02-08 19:42:07 -08:00
Vinnie Falco
97126f18b1 Add /crawl cgi request feature to peer protocol (RIPD-729):
This adds support for a cgi /crawl request, issued over HTTPS to the configured
peer protocol port. The response to the request is a JSON object containing
the node public key, type, and IP address of each directly connected neighbor.
The IP address is suppressed unless the neighbor has requested its address
to be revealed by adding "Crawl: public" to its HTTP headers. This field is
currently set by the peer_private option in the rippled.cfg file.
2015-02-08 19:42:01 -08:00
Vinnie Falco
3838d222c2 NuDB: limit size of mempool (RIPD-787):
Insert now blocks when the size of the memory pool exceeds a predefined
threshold. This solves the problem where sustained insertions cause the
memory pool to grow without bound.
2015-02-08 19:41:54 -08:00
Vinnie Falco
96c3292210 Add missing include 2015-02-08 19:41:48 -08:00
Vinnie Falco
b0fd92cb3f Fix unsafe iterator dereference in PeerFinder 2015-02-08 19:41:43 -08:00
Vinnie Falco
62c5b5e570 Add general delimiter split() to rfc2616 2015-02-07 15:19:55 -08:00
Vinnie Falco
feaa0871ac Add lz4 2015-02-07 06:38:37 -08:00
Vinnie Falco
9f41976926 Merge commit '1784f24c5f81e864bf0ad8dcfdf4266ca1108290' as 'src/lz4' 2015-02-05 15:40:04 -08:00
Vinnie Falco
1784f24c5f Squashed 'src/lz4/' content from commit e25b51d
git-subtree-dir: src/lz4
git-subtree-split: e25b51de7b51101e04ceea194dd557fcc23c03ca
2015-02-05 15:40:04 -08:00
Vinnie Falco
fc47d9fc4d Set version to 0.28.0-b4 2015-02-03 16:24:34 -08:00
Vinnie Falco
eade9f8f2b Revert RocksDB backend settings:
This reverts the change that makes RocksDBQuick the default settings for
node_db "type=rocksdb". The quick settings can be obtained by setting
"type=rocksdbquick".

RocksDBQuick settings are implicated in memory over-utilization problems
seen recently.
2015-02-03 16:24:34 -08:00
Vinnie Falco
6276c55cc9 Set version to 0.27.0-sp1 2015-02-03 14:58:02 -08:00
Vinnie Falco
afa6ff7c4b Revert RocksDB backend settings:
This reverts the change that makes RocksDBQuick the default settings for
node_db "type=rocksdb". The quick settings can be obtained by setting
"type=rocksdbquick".

RocksDBQuick settings are implicated in memory over-utilization problems
seen recently.
2015-02-03 14:57:54 -08:00
Vinnie Falco
f4dcbe3a84 Remove spurious call to fetch in NuDBBackend 2015-02-03 12:56:35 -08:00
Vinnie Falco
9c02cc1b17 Add /crawl cgi request feature to peer protocol (RIPD-729):
This adds support for a cgi /crawl request, issued over HTTPS to the configured
peer protocol port. The response to the request is a JSON object containing
the node public key, type, and IP address of each directly connected neighbor.
The IP address is suppressed unless the neighbor has requested its address
to be revealed by adding "Crawl: public" to its HTTP headers. This field is
currently set by the peer_private option in the rippled.cfg file.
2015-02-03 12:56:35 -08:00
seelabs
0cc3ef8f90 Add missing include:
* Compile previously failed on Mac with clang
2015-02-03 12:56:32 -08:00
Tom Ritchford
4cbbacc946 Set version to 0.28.0-b3 2015-02-02 17:01:50 -08:00
Vinnie Falco
9a0c71d4a7 NuDB: limit size of mempool (RIPD-787):
Insert now blocks when the size of the memory pool exceeds a predefined
threshold. This solves the problem where sustained insertions cause the
memory pool to grow without bound.
2015-02-02 17:01:19 -08:00
Vinnie Falco
0f1b831de7 Add missing include 2015-02-02 17:01:18 -08:00
Vinnie Falco
37a7a2aacd Fix unsafe iterator dereference in PeerFinder 2015-02-02 17:01:18 -08:00
Tom Ritchford
635b157b11 Fix C++ guards in beast. 2015-02-02 17:01:18 -08:00
Tom Ritchford
c3ae4da83a Fix include guards in rippled. 2015-02-02 17:01:17 -08:00
Tom Ritchford
c3809ece67 New RPC method "version". 2015-02-02 17:01:17 -08:00
Howard Hinnant
bfc436dccd Add metadata to transaction difference logging: RIPD-775 2015-02-02 17:01:16 -08:00
Nik Bougalis
71d6874236 Set version to 0.28.0-b2 2015-01-28 16:34:33 -08:00
Vinnie Falco
9bf1f994ae Remove buffer_view 2015-01-28 16:34:33 -08:00
Vinnie Falco
bb4127a6fb Refactor Serializer and SerializerIterator interfaces:
* Remove unused members
* SerialIter holds only a pointer and offset now
* Use free functions for some Serializer members
* Use SerialIter in some places instead of Serializer
2015-01-28 16:34:33 -08:00
Edward Hennis
a691632995 Support a "--noserver" command line option in tests:
* Run npm/integration tests without launching rippled, using a
  running instance of rippled (possibly in a debugger) instead.
* Works for "npm test" and "mocha"
2015-01-28 16:34:33 -08:00
Miguel Portilla
5d6ea3d75f Combine history_ledger_index and online_delete (RIPD-774) 2015-01-28 16:34:33 -08:00
Mark Travis
43873b1b2c Initialize canDelete_ properly in the constructor. 2015-01-28 16:34:33 -08:00
Mark Travis
9430f3665b Speed up access to ledger index value that can be deleted. 2015-01-28 16:34:33 -08:00
Vinnie Falco
f3c1f63444 Remove LevelDB and HyperLevelDB backends:
The LevelDB and HyperLevelDB are removed from the backend choices. Neither
were recommended for production environments. As RocksDB is not available
on Windows platforms yet, the recommended backend choice for Windows is NuDB.
2015-01-28 13:43:00 -08:00
Nik Bougalis
b5c7232d6f Set version to 0.28.0-b1 2015-01-27 18:21:54 -08:00
Edward Hennis
2f3677d593 Change timing on "sequence realignment" test. 2015-01-27 18:21:54 -08:00
Howard Hinnant
1e0efaffe8 Add missing includes. 2015-01-27 18:21:54 -08:00
Vinnie Falco
fc79754750 Remove unused SHAMap fields 2015-01-26 19:25:38 -08:00
Miguel Portilla
0e4de42be8 Add RPC metrics (RIPD-705)
Add metrics to record the number of RPC requests received. Record the number of
node store fetches performed per request. Additionally record the byte size of
each request response and measure the response time of each request in
milliseconds.

A new class, ScopedMetrics, uses the Boost Thead Local Storage mechanism to
efficiently record NodeStore metrics within the same thread.
2015-01-26 19:25:38 -08:00
Scott Determan
4e389127b5 Use microsecond granularity for sqlite lock backoff algorithm:
When sql tries to acquire a lock that is already held, it sleeps for some
microseconds using the usleep function and then try to acquire the lock
again. However, if the HAVE_USLEEP macro is not defined then the sleep
function will be used.

This fix will define HAVE_USLEEP even when it is not already defined by
the system. Although some Linux distros may not define HAVE_USLEEP,
all supported versions provide usleep. If the system does not actually
have a usleep function, then the compiler will flag the error.
2015-01-26 19:13:40 -08:00
Nik Bougalis
47593730d6 Modernize code:
* Clean STBase-derived class creation interfaces
* Annotate overriden STBase virtual functions
* Optimize path deserialization
* Prefer range-based for
* Prefer std::unique_ptr
* Remove BOOST_FOREACH
2015-01-26 19:13:40 -08:00
Tom Ritchford
e742da73bd Simplify lookupLedger(). 2015-01-26 19:13:40 -08:00
Vinnie Falco
890bf3cce1 Add PeerFinder Logic backoff unit test 2015-01-26 19:13:40 -08:00
Nik Bougalis
60eb312e3b Fix order of construction of Application members 2015-01-26 19:13:40 -08:00
Tom Ritchford
06207da185 Move Context.h up into rpc/. 2015-01-26 19:13:40 -08:00
Nicholas Dudfield
4dc2cf8a6b Update tests to support latest ripple-lib:
* Update ripple-lib api usage
* Use latest npm ripple-lib
  * Tested with bignumber.js branch and tip of develop
* Use new version of coffee-script
  * Better source maps
* Update mocha
* Add assert-diff for better error reporting
* Add rconsole, enabled via USE_RCONSOLE env var
  * For use with manual installation only
2015-01-26 19:13:40 -08:00
Scott Determan
44450bf644 Enable Amendments from config file or static data (RIPD-746):
* The rippled.cfg file has a new section called "amendments"

* Each line in this section contains two white-space separated items
** The first item is the ID of the amendment (a 256-bit hash)
** The second item is the friendly name

* Replaces config section name macros with variables

* Make addKnown arguments safer

* Added lock to addKnown
2015-01-26 19:13:02 -08:00
Nik Bougalis
312aec79ca Remove WalletAdd (RIPD-725) 2015-01-26 12:39:13 -08:00
Nik Bougalis
a8578c73f8 Remove support for deprecated PreviousTxnID field (RIPD-710):
The PreviousTxnID field has been deprecated and should not be used for
transactions that use the field will now be rejected.

The AccountTxnID feature should be used instead by enabling transaction
tracking and specifying a transaction ID at submission. More details
are available at: https://ripple.com/build/transactions/#accounttxnid
2015-01-26 12:39:13 -08:00
Miguel Portilla
c522ffa6db Eliminate temREDUNDANT_SEND_MAX (RIPD-590):
The rules for when a SendMax is redundant are complicated. It is easier to
always allow a SendMax and eliminate temREDUNDANT_SEND_MAX.
2015-01-26 12:39:13 -08:00
Nik Bougalis
93b7599b1c Fix missing 'else' when handling sfMessageKey:
When clearing out a message key the transactor would incorrectly
create an empty `sfMessageKey` field instead of simply deleting
the field.

Clarify logic by reordering checks.
2015-01-26 12:39:13 -08:00
Nik Bougalis
3ccbd7c9b2 Finalize autobridging implementation (RIPD-179):
Autobridging uses XRP as a natural bridge currency to allow IOU-to-IOU orders
to be satisfied not only from the direct IOU-to-IOU books but also over the
combined IOU-to-XRP and XRP-to-IOU books.

This commit addresses the following issues:

* RIPD-486: Refactoring the taker into a unit-testable architecture
* RIPD-659: Asset-aware offer crossing
* RIPD-491: Unit tests for IOU to XRP, XRP to IOU and IOU to IOU
* RIPD-441: Handle case when autobridging over same owner offers
* RIPD-665: Handle case when autobridging over own offers
* RIPD-273: Groom order books while crossing
2015-01-26 12:39:13 -08:00
Nik Bougalis
385a87db31 Claim a fee when a required destination tag is not specified (RIPD-574) 2015-01-26 12:39:12 -08:00
Nik Bougalis
5530353eef Add simplified explicit interfaces to handle XRP and IOU transfers:
The new interfaces take into account the different semantics of XRP, which
do not have an issuer or transfer fees, and IOUs which have issuers and
(optional) transfer fees.

For XRP, the new `LedgerEntrySet::transfer_xrp` will transfer the specified
amount of XRP between from a given source to a given destination.

For IOU, two new functions are introduced:
* `LedgerEntrySet::issue_iou` which transfers the specified amount of an
IOU from the IOU's issuer to an account.
* `LedgerEntrySet::redeem_iou` which transfers the specified amount of an
IOU from an account to the IOU's issuer.

A transfer from user-to-user (e.g. to fill an order during offer crossing)
requires the use of `redeem_iou` followed by `issue_iou`. This helps to
enforce the Ripple invariant that IOUs never flow directly from user to
user, but only through a gateway. Additionally, this  allows for the
explicit calculation and application of transfer fees by varying the
amounts redeemed and issued.

The new interfaces promote type safety since you cannot use the issue
and redeem APIs with XRP or the transfer API with IOU, and the issuer
to be used is implied by the currency being issued or redeemed.
2015-01-26 12:39:12 -08:00
Nik Bougalis
d1193093ef Require the master key when performing certain operations (RIPD-666):
* When disabling the use of the master key; or
* When enabling 'no freeze'.
2015-01-26 12:39:12 -08:00
David Schwartz
b203db27a4 Fix offer->ACCOUNT->offer 2015-01-26 12:39:12 -08:00
JoelKatz
0a3e1af04c When pathfinding, don't output a redundant account node 2015-01-26 12:39:12 -08:00
Vinnie Falco
c6c8e5d70c Set version to 0.27.0 2015-01-26 10:56:11 -08:00
Nik Bougalis
fa354ec8d9 Set version to 0.27.0-b11 2015-01-23 17:37:18 -08:00
Nik Bougalis
d0375f697d Invoke correct deleter 2015-01-23 17:34:30 -08:00
Vinnie Falco
33c8257d25 Set version to 0.27.0-b10 2015-01-21 15:25:11 -08:00
Scott Determan
f389bc33c3 VSProject: Handle tuples in CPPDEFINES:
The VSProject generator now handles tuples in addition to strings and
dicts when converting environment variables such as CPPDEFINES.
2015-01-21 15:20:06 -08:00
Vinnie Falco
4d5dca71ce Squelch Peerfinder fixed connection attempts 2015-01-21 14:59:47 -08:00
Vinnie Falco
a9c44a1b9c Set version to 0.27.0-b9 2015-01-21 14:23:50 -08:00
Vinnie Falco
4144f800a1 Fix PeerImp concurrent access of socket:
The PeerImp::run launch function is now dispatched on the strand to prevent
undefined behavior resulting from concurrent access to the ssl::stream object.
2015-01-21 14:21:43 -08:00
Vinnie Falco
6ef9a81017 Set version to 0.27.0-b8 2015-01-21 14:21:43 -08:00
Vinnie Falco
8c6722f3c5 Remove use of date and time from rocksdb unity build 2015-01-21 14:21:43 -08:00
Vinnie Falco
40e138627b Fixes to Overlay:
* Make ~Peer virtual
* Call close in ConnectAttempt::stop
* Handle nullptr return in new_outbound_slot
* Check gracefulClose_ in read loop
2015-01-21 10:48:32 -08:00
Vinnie Falco
a470dda4e6 Fix Journal::Stream::active to return the correct value 2015-01-21 10:48:32 -08:00
Edward Hennis
b725410623 Option to specify rippled path on command line.
* --rippled=<absolute or relative path>
* Works for "npm test" and "mocha"
* Remove "rippled_path" from config.js to require CLI path.
2015-01-21 10:48:31 -08:00
Miguel Portilla
a9dfb33126 Log abnormal close time offsets (RIPD-572) 2015-01-21 10:48:31 -08:00
Miguel Portilla
8b848770dc Add config "ledger_history_index" functionality (RIPD-559) 2015-01-21 10:48:31 -08:00
Vinnie Falco
94629edb9b Add NuDB backend:
The NuDB database backend is a high performance key/value store presented
as an alternative to RocksDB on Mac and Linux deployments, and the preferred
backend option for Windows deployments. The LevelDB backend is deprecated for
all platforms.

This includes these changes:

* Add Backend::verify API for doing consistency checks
* Add Database::close so caller can catch exceptions
* Improved Timing test for NodeStore creates a simulated workload
2015-01-21 10:48:30 -08:00
Vinnie Falco
2a3f2ca28d Add NuDB: A Key/Value Store For Decentralized Systems
NuDB is a high performance key/value database optimized for insert-only
workloads, with these features:

* Low memory footprint
* Values are immutable
* Value sizes from 1 2^48 bytes (281TB)
* All keys are the same size
* Performance independent of growth
* Optimized for concurrent fetch
* Key file can be rebuilt if needed
* Inserts are atomic and consistent
* Data file may be iterated, index rebuilt.
* Key and data files may be on different volumes
* Hardened against algorithmic complexity attacks
* Header-only, nothing to build or link
2015-01-21 10:48:30 -08:00
Edward Hennis
8ab1e7d432 Integration test to subscribe to offer books. 2015-01-20 16:45:04 -08:00
Miguel Portilla
b2ba6a0c85 Fix RPC subscribe with multiple books 2015-01-20 16:45:04 -08:00
Tom Ritchford
cca5421aed Fix Subscribe RPC to correctly distinguish bids and asks. 2015-01-20 16:45:04 -08:00
Nik Bougalis
799d9a73e6 Ensure that hash_append will never throw
Conflicts:
	src/beast/beast/net/IPAddress.h
2015-01-20 16:45:03 -08:00
Scott Determan
b0781622b2 Handle nullptr return values to InboundLedgers::findCreate
In normal operation, InboundLedgers::findCreate never returns null, but
during system shutdown, it will return null.

Since this only happens in system shutdown, when findCreate returns null
the calling function stops what it was doing and returns.

During testing, an issue where destroying the application object
and creating a new one caused problems with a static PathTable. This table
is now cleared when re-initialized.
2015-01-20 16:45:03 -08:00
Tom Ritchford
0d0eec6345 Clean up test documentation and a log message. 2015-01-20 16:45:03 -08:00
Nik Bougalis
1af79f7960 Properly validate the configured online delete interval 2015-01-20 16:45:03 -08:00
Vinnie Falco
15b570bbdd Add profile targets for gcc and clang 2015-01-20 16:45:02 -08:00
Tom Ritchford
7aa5599cc2 Remove unused parameter in two lambdas. 2015-01-20 16:45:02 -08:00
JoelKatz
676293ec42 Ensure account_tx queries over and returns correct range 2015-01-20 16:45:02 -08:00
Nik Bougalis
abc4fb81b1 Improve RippleLineCache hashing 2015-01-20 16:45:01 -08:00
Vinnie Falco
53a16f354f Add hardened_hash to basics/:
xxhasher is the default hash function for hardened_hash.
2015-01-20 16:45:01 -08:00
Vinnie Falco
6ab1ecd836 Tidy up container hash functions:
* Add xxhasher
* Move fnv1a, siphash, spookyto hash/
* Move hash_append, uhash to hash/
* Move hash_speed_test to hash/
* Move hash classes to individual header files
* Remove hardened_hash
2015-01-20 16:45:01 -08:00
Vinnie Falco
e7b16e7b47 Add rngfill 2015-01-20 16:45:01 -08:00
Vinnie Falco
14804f81a8 Optimize calls to unit_test::suite::expect:
This changes expect and unexpected to receive the reason text as a
template argument, allowing the std::string conversion of char const*
parameters to take place only if the condition evaluates to false. This
cuts all calls to malloc and free on tests that pass.
2015-01-20 16:45:00 -08:00
Vinnie Falco
9a61b8d77d Declare base_uints with using statements 2015-01-20 16:45:00 -08:00
Vinnie Falco
f42c2763d5 Improve streambuf unit test 2015-01-20 16:45:00 -08:00
Vinnie Falco
98d4e0e1b5 Fix ZeroCopyOutputStream:
Added a destructor that commits the last block of data
if there was no final call to BackUp.
2015-01-20 16:45:00 -08:00
Tom Ritchford
9156633baf Set version to 0.27.0-b7 2015-01-20 17:59:55 -05:00
Tom Ritchford
bcf4f836b4 Use websocketpp_02 namespace. 2015-01-20 17:08:15 -05:00
Vinnie Falco
dbc1d70f99 Set version to 0.27.0-b6 2015-01-20 09:41:27 -08:00
Vinnie Falco
78bc190a85 Merge commit '02855d7fed46d3c1aa1f2cefbcf4a42720575c3f' as 'src/websocketpp' 2015-01-20 09:35:00 -08:00
Vinnie Falco
02855d7fed Squashed 'src/websocketpp/' content from commit 875d420
git-subtree-dir: src/websocketpp
git-subtree-split: 875d420952
2015-01-20 09:35:00 -08:00
Vinnie Falco
6fdd5d32be Rename websocket/ to websocketpp_02 2015-01-20 09:34:54 -08:00
Vinnie Falco
d7f32b105b Set version to 0.27.0-b5 2015-01-13 11:50:58 -08:00
Vinnie Falco
0ac480a0bd Fix extra increment in GenerateRootDeterministicKey 2015-01-13 11:49:59 -08:00
Tom Ritchford
417996de02 Set version to 0.27.0-b4 2015-01-13 11:30:23 -05:00
Tom Ritchford
6c2d60cec2 Prevent RPC handlers from returning non-objects. 2015-01-13 11:30:23 -05:00
Tom Ritchford
743bd6c917 Fix RPC command logrotate to return a Json object. 2015-01-13 11:30:14 -05:00
Edward Hennis
ab61aa41d9 Set version to 0.27.0-b3 2015-01-12 18:00:55 -05:00
Edward Hennis
36396ae29e rippled.cfg [db_node] options for RocksDB
* open_files and compression.
2015-01-12 18:00:54 -05:00
Vinnie Falco
749e083e6e NodeStore improvements:
* Add Backend::verify API for doing consistency checks
* Add Database::close so caller can catch exceptions
* Improved Timing test for NodeStore creates a simulated workload
2015-01-12 18:00:52 -05:00
Vinnie Falco
67b9cf9e82 Improved support for exceptions in threads spawned by unit tests:
Unit tests that wish to spawn threads for testing concurrency may now do so
by using unit_test::thread as a replacement for std::thread. These threads
propagate unhandled exceptions to the unit test, and work with the abort on
failure feature.
2015-01-12 17:17:09 -05:00
Vinnie Falco
27fb20f3ab Add xor_shift_engine 2015-01-12 17:17:07 -05:00
Josh Juran
1c71b274f0 SConstruct: Add ed25519.c
Conflicts:
	Builds/VisualStudio2013/RippleD.vcxproj
	Builds/VisualStudio2013/RippleD.vcxproj.filters
	SConstruct
2015-01-12 12:16:26 -08:00
Vinnie Falco
fcd20b63fe Merge commit '8ec344ac1b6c66d936fa0f7005490e126a434a70' as 'src/ed25519-donna' 2015-01-12 11:27:15 -08:00
Vinnie Falco
8ec344ac1b Squashed 'src/ed25519-donna/' content from commit 04223b0
git-subtree-dir: src/ed25519-donna
git-subtree-split: 04223b04e22f5eff32c6c27e25194d4d984c6f41
2015-01-12 11:27:15 -08:00
Vinnie Falco
df966a9ac6 Set version to 0.27.0-b2 2015-01-05 18:49:18 -08:00
Vinnie Falco
f634666dc6 Make rocksdbquick settings default:
This removes the old default configuration for the "rocksdb" backend and
replaces it with the configuration that was formerly available using
the experimental backend "rocksdbquick".

The new configuration setting improves the performance of the key/value
database by changing the compaction style and tuning the size parameters for
the typical rippled workload. Testing shows a decrease in I/O spikes for both
reading and writing.
2015-01-05 18:49:17 -08:00
Tom Ritchford
e2f9f5d7e5 Fix compilation warnings. 2015-01-05 18:49:17 -08:00
Tom Ritchford
d078b0d143 Extract the git ID into a separate compilation unit. 2015-01-05 18:49:15 -08:00
Nik Bougalis
0ccdea3cd8 Disable Ticket transactions and tests 2015-01-05 14:18:27 -08:00
Vinnie Falco
df54b47cd0 Tidy up includes and add modules to the classic build:
An alternative to the unity build, the classic build compiles each
translation unit individually. This adds more modules to the classic build:

* Remove unity header app.h
* Add missing includes as needed
* Remove obsolete NodeStore backend code
* Add app/, core/, crypto/, json/, net/, overlay/, peerfinder/ to classic build
2015-01-05 13:35:57 -08:00
Vinnie Falco
2e595830b3 Levelize SHAMap:
The SHAMap class is refactored into a separate module where each translation
unit compiles separate without errors. Dependencies on higher level business
logic are removed. SHAMap now depends only on basics, crypto, nodestore,
and protocol:

* Inject NodeStore::Database& to SHAMap
* Move sync filter instances to app/ledger/
* Move shamap to its own module
* Move FullBelowCache to shamap/
* Move private code to shamap/impl/
* Refactor SHAMap treatment of missing node handler
* Inject and use Journal for logging in SHAMap
2015-01-05 11:46:11 -08:00
Vinnie Falco
96fbcc9a5a Refactor NodeStore:
Manager is changed to be a Meyer's singleton, with factories automatically
registering upon construction.
2015-01-05 11:46:11 -08:00
Vinnie Falco
6283801981 Add non-unity build targets:
The SConstruct is modified to provide a new family of targets, ending with
the suffix ".nounity", which compile individual translation units instead of
some of the unity translation units ("classic" builds). Two modules updated
for this treatment are ripple/basics/ and ripple/protocol/, with plans to
update more in the future. A consequence is longer build times in some cases.
A benefit of classic builds is that missing includes can be identified
through compiler errors.
2015-01-05 11:46:11 -08:00
Vinnie Falco
9a3214d46e Normalize files containing unit test code:
Source files are split to place all unit test code into translation
units ending in .test.cpp with no other business logic in the same file,
and in directories named "test".

A new target is added to the SConstruct, invoked by:
    scons count
This prints the total number of source code lines occupied by unit tests,
in rippled specific code and excluding library subtrees.
2015-01-05 11:46:07 -08:00
Vinnie Falco
9eb7c8344f Don't leak track StringPairArray 2015-01-05 11:44:15 -08:00
Vinnie Falco
4140bbb1f7 Set version to 0.27.0-b1 2015-01-05 11:37:01 -08:00
Vinnie Falco
ea44497136 Fix msvc ICE on initializer-list 2015-01-05 11:37:00 -08:00
Nik Bougalis
07737c6e5b Add 'delivered_amount' to Transaction JSON (RIPD-643):
The synthetic field 'delivered_amount' can be used to determine the exact
amount delivered by a Payment without having to check the DeliveredAmount
field, if present, or the Amount field otherwise.

The field is only returned when metadata is available and the data is not
returned in binary format.
2014-12-31 01:55:10 -08:00
JoelKatz
98d5eefc86 Pathfinding bugfixes (RIPD-735):
* Fix specifying paths and search level for ripple_path_find
* Don't modify the pathfinder, it has issuer-neutral paths.
* Handle previous paths correctly
* Compare paths correctly
2014-12-31 01:55:10 -08:00
JoelKatz
4f2d93bb65 Avoid processing transactions if we need a network ledger
Not processing tranasctions without a network ledger makes
initial network synchronization faster.
2014-12-31 01:55:10 -08:00
Edward Hennis
a5df3f1747 Support a "no_server" flag in test config.
* Will use a running instance of rippled (possibly in a debugger).
* Modify all tests to respect the server_default value.
* Fail test if new account already exists and has a balance.
* README.md with instructions for advanced test debugging, particularly using no_server.
2014-12-31 01:55:10 -08:00
Howard Hinnant
7f5f73887d Fix undefined behavior 2014-12-31 01:55:10 -08:00
Nik Bougalis
91ce7807b9 Remove legacy LoadTypes (RIPD-365) 2014-12-31 01:55:10 -08:00
Nik Bougalis
d26fae9875 Reduce Beast dependencies by leveraging C++11 features:
* Remove beast::Atomic (RIPD-728):
  * Use std-provided alternatives
  * Eliminate atomic variables where possible

* Cleanup beast::Thread interface:
  * Use std::string instead of beast::String
  * Remove unused functions and parameters

* Remove unused code:
  * beast::ThreadLocalValue
  * beast::ServiceQueue
2014-12-31 01:55:10 -08:00
Nik Bougalis
60bdc79ec4 Remove unused sitefiles module 2014-12-30 12:33:41 -08:00
Tom Ritchford
253ddf2998 Split off CheckLibraryVersions.test.cpp. 2014-12-30 12:33:41 -08:00
Nik Bougalis
9fa15b390a Always initialize LedgerHandler options field 2014-12-29 11:21:19 -08:00
Josh Juran
e7d6fe6c8b Cull duplicate/unused code in RippleAddress:
Deduplicate a call to GeneratePublicDeterministicKey().
Remove unused member functions.
2014-12-29 11:21:19 -08:00
Tom Ritchford
9650b1aa70 New ripple::TestSuite with method expectEquals(). 2014-12-29 11:21:19 -08:00
Howard Hinnant
eafa6f960f API for improved Unit Testing (RIPD-432):
* Added new test APIs allowing easy ways to create ledgers, apply
  transactions to them, close and advance them.

* Moved Ledger tests from Ledger.cpp to Ledger.test.cpp.

* Changed several TransactionEngine log priorities from lsINFO to lsDEBUG to
  reduce unnecessary verbosity in the log messages while running these tests.

* Moved LedgerConsensus:applyTransactions from a private member function to a
  free function so that it could be accessed externally, and without having to
  reference a LedgerConsensus object.  This was done to facilitate the new
  testing API.
2014-12-29 11:21:19 -08:00
Yana
c62ccf4870 Update README.md (RIPD-601) 2014-12-29 11:21:19 -08:00
Vinnie Falco
ef34439a79 Set version to 0.26.5-rc1 2014-12-22 15:20:03 -08:00
Nik Bougalis
b328ec2462 Prevent passing of non-POD types to POD-only interfaces:
This tidies up the code that produces random numbers to conform
to programming best practices and reduce dependencies.

* Use std::random_device instead of platform-specific code
* Remove RandomNumbers class and use free functions instead
2014-12-22 15:19:48 -08:00
Vinnie Falco
60f27178b8 Levelization, improve structure of source files:
Source files are moved between modules, includes changed and added,
and some code rewritten, with the goal of reducing cross-module dependencies
and eliminating cycles in the dependency graph of classes.

* Remove RippleAddress dependency in CKey_test
* ByteOrder.h, Blob.h, and strHex.h are moved to basics/. This makes
  the basics/ module fully independent of other ripple sources.
* types/ is merged into protocol/. The protocol module now contains
  all primitive types specific to the Ripple protocol.
* Move ErrorCodes to protocol/
* Move base_uint to basics/
* Move Base58 to crypto/
* Remove dependence on Serializer in GenerateDeterministicKey
* Eliminate unity header json.h
* Remove obsolete unity headers
* Remove unnecessary includes
2014-12-22 10:23:49 -08:00
Vinnie Falco
e3fbb83ad0 Tidy up usage of std::begin, std::end 2014-12-19 11:55:43 -08:00
Nik Bougalis
28b70a7b9a Remove 'Proof of Work' code 2014-12-19 11:00:29 -08:00
Nicholas Dudfield
dcdc341d0f Add appveyor 2014-12-19 11:00:29 -08:00
Tom Ritchford
fce77c9372 Configuration for yielding RPC server. 2014-12-19 11:00:28 -08:00
Tom Ritchford
a360c481c2 Refactor out a version of lookupLedger returning Status. 2014-12-19 11:00:28 -08:00
Tom Ritchford
c72db5fa5f Refactor away RPCHandler::doRpcCommand 2014-12-19 11:00:28 -08:00
Tom Ritchford
fc9a23d6d4 Send output incrementally in ServerHandlerImp. 2014-12-19 11:00:27 -08:00
Tom Ritchford
167f4666e2 New generic Ledger RPC handler. 2014-12-19 11:00:27 -08:00
Tom Ritchford
1cbcc7be21 Allow the Ledger to generically output to both Json models. 2014-12-19 11:00:27 -08:00
Tom Ritchford
8053598069 Better interoperation between Json::Value and JsonObject.
* Generic functions to add entries to both object models.
* Add Json::Value into JsonObjects.
* Write Json::Value to string incrementally.
* Get rid of ripple::RPC::New namespace
2014-12-19 11:00:26 -08:00
Tom Ritchford
7cfac1a91a Wrap Output in a coroutine that periodically yields. 2014-12-19 11:00:26 -08:00
Tom Ritchford
192cdd028e Change Output to be a generic std::function. 2014-12-19 11:00:26 -08:00
Tom Ritchford
029c143922 Add a comment to ledger/Ledger.h. 2014-12-19 11:00:26 -08:00
Tom Ritchford
00298cc68c Simplify LedgerData.cpp. 2014-12-19 11:00:25 -08:00
Tom Ritchford
d9c7db51af Make three ErrorCode functions generic. 2014-12-19 11:00:25 -08:00
Vinnie Falco
f12b15d22b Fix logic in HTTP/S server:
These bugs do not affect production code since callers do not invoke
`write` multiple times, but these would become a problem in the future.

* Access to Peer::write_queue_ is synchronized correctly.
* Remove unsafe access to deleted container element.
2014-12-19 11:00:25 -08:00
Vinnie Falco
409b8bac00 Remove unused and obsolete Ripple identifiers and tidy up:
These identifiers were part of a failed set of classes to replace
the functionality combined into RippleAddress. They are not used
and therefore can be removed.

* Remove RippleAccountPrivateKey
* Remove RippleAccountPublicKey
* Remove RippleAccountID
* Remove RipplePrivateKey
* Remove RipplePublicKeyHash
* Remove RippleLedgerHash
* Remove unused withCheck argument
* Remove CryptoIdentifier
* Remove IdentifierStorage
* Remove IdentifierType
* Remove SimpleIdentifier
* Add missing include
2014-12-19 11:00:24 -08:00
Vinnie Falco
28b09bde4b Simplify RipplePublicKey:
This implements the bare minimum necessary to store a 33 byte public
key and use it in ordered containers. It is an efficient and well
defined alternative to RippleAddress when the caller only needs
a node public key.
2014-12-19 11:00:24 -08:00
Vinnie Falco
2f6af906f4 Validators work (RIPD-703):
This replaces the experimental validators module with foundational
code to implement a new system for tracking validators, validations and
the UNL. The code is turned off by default, in BeastConfig.h

* Remove obsolete public Manager interfaces
* Remove obsolete database methods
* Remove obsolete ChosenList concept
* Remove obsolete code
* Add missing includes
* Tidy up STValidation.h
* Move factory function to Validators::make_Manager
* Add Connection object for tracking STValidations
2014-12-19 11:00:23 -08:00
Vinnie Falco
628e3ac1eb Add waitable_executor 2014-12-18 10:26:55 -08:00
Josh Juran
fbf5785e35 Combine STTx::checkSign overloads:
Callers don't need to specify the signing key -- they're just retrieving
the key from the SerializedTransaction and then passing it back.

This simplifies Ed25519 implementation.
2014-12-12 20:14:02 -08:00
Nicholas Dudfield
eeea2b1ff8 Use ppa:afrank/boost 1.57 for Travis 2014-12-12 20:14:02 -08:00
Vinnie Falco
32062e439f Split peer connect logic to another class (RIPD-711):
All of the logic for establishing an outbound peer connection including
the initial HTTP handshake exchange is moved into a separate class. This
allows PeerImp to have a strong invariant: All PeerImp objects that exist
represent active peer connections that have already gone through the
handshake process.
2014-12-12 20:14:02 -08:00
Vinnie Falco
930a0beaf1 Add ZeroCopyOutputStream and tidy up 2014-12-12 20:14:02 -08:00
Nik Bougalis
4a49fefdd9 Various cleanups:
* Replace SYSTEM_NAME and other macros with C++ constructs
* Remove RIPPLE_ARRAYSIZE and use std::extent or ranged for loops
* Remove old-style, unused offer crossing unit test
* Make STAmount::saFromRate free and remove default argument
2014-12-12 20:14:02 -08:00
Nik Bougalis
8e792855e0 Do not use path if path expansion fails 2014-12-10 16:55:06 -08:00
Tom Ritchford
69f5c6987a Whitespace: clean WebSockets to 80 columns. 2014-12-10 16:55:06 -08:00
Nik Bougalis
85fc9e4ecf Revert e4c9822d78 "Enable processor-specific optimizations when available:" 2014-12-08 14:54:03 -08:00
Mark Travis
d5c3f0c9cf Stability bugfixes for online delete SHAMapStore:
The correct ledger age is necessary for checking health
status, and the previous behavior caused the online deletion process to
abort if the process took too long.

The tuning parameter added and the parameter whose default was modified both
minimize impact of SQL DELETE operations by decreasing the default batch size
for deletes and for increasing the backoff period between deletion batches.
These parameters decrease contention for the SQLite and I/O with the trade-off
of longer processing time for online delete. Online-delete is not a
time-critical function, so a little slowness in wall-clock time is not harmful.
2014-12-08 14:54:03 -08:00
JoelKatz
a48120e675 Fix incorrect source issuer for XRP source 2014-12-08 14:54:03 -08:00
Nik Bougalis
36f8e4f2ad Improve hex conversion & parsing routines 2014-12-08 14:54:03 -08:00
David Schwartz
1084a39a45 Improve the humanAccountID cache (RIPD-693)
Profiling indicated some performance issues coming from the
cache of 160-bit account IDs to base58 format. This replaces
the single cache with two caches and rotates out old
entries.
2014-12-08 14:54:03 -08:00
Tom Ritchford
86df482842 Make sure that handlers always return Json::objectValue. 2014-12-01 17:16:24 -05:00
Tom Ritchford
b0d47ebcc6 Use better base64 handling in ServerHandlerImp. 2014-12-01 17:15:23 -05:00
Tom Ritchford
fffdf1dfba Make beast::detail::chunk_encoded_buffers::to_hex() static 2014-12-01 11:12:59 -05:00
Tom Ritchford
3273ed2616 Remove unused BEAST_COMPILER_CHECKS_SOCKET_OVERRIDES. 2014-12-01 10:56:03 -05:00
Vinnie Falco
aa7b0a31b0 Refactor protocol message parsing:
This replaces the stateful class parser with a stateless free function.
The protocol buffer message is parsed using a ZeroCopyInputStream.

* Invoke method is now a free function.
* Protocol handler doesn't need to derive from an abstract interface
* Only up to one message is processed at a time by the invoker.
* Remove error_code return from the handler's message processing functions.
* Add ZeroCopyInputStream implementation that wraps a BufferSequence.
* Free function parses up to one protocol message and calls the handler.
* Message type and size can be calculated from an iterator
  range or a buffer sequence.
2014-11-26 12:23:21 -08:00
Vinnie Falco
fb0d44d403 Use cluster state in Slot instead of PeerImp 2014-11-26 12:23:10 -08:00
Vinnie Falco
cd8ec89cbb Use injections from OverlayImpl in PeerImp 2014-11-26 12:23:02 -08:00
Vinnie Falco
252f271dc5 Fixes to beast::asio::streambuf:
* Fix to_string conversion
* Fix assert on debug invariant checks
* Fix the treatment of the output position when the entire output is committed.
* Add unit test
2014-11-26 12:22:55 -08:00
Vinnie Falco
62d400c3a9 Move the call to cancel_timer to the right place 2014-11-26 12:22:46 -08:00
Scott Schurr
f9aa3e0da5 Add more unit tests to rpc/impl/TransactionSign (RIPD-480):
By adding a mock it is possible to test the transactionSign
function without interacting with the ledger.  This is the
smallest change I could come up with that allows transactionSign
to be unit tested.

The unit tests are white boxed.  Each test case is a result
of examining the code and identifying behavior associated with
different JSON fields.  That means the tests are not based on
requirements, they are based on observed behavior.
2014-11-26 12:07:44 -08:00
Vinnie Falco
685fe5b0fb Don't call std::exit on clean exit 2014-11-25 19:19:56 -08:00
Vinnie Falco
5180e71a0d Remove unused chrono::time_point stream conversions 2014-11-25 19:19:56 -08:00
Vinnie Falco
55637f7508 Template abstract_clock on Clock:
The abstract_clock is now templated on a type meeting the requirements of
the Clock concept. It inherits the nested types of the Clock on which it
is based. This resolves a problem with the original design which broke the
type-safety of time_point from different abstract clocks.
2014-11-25 19:19:56 -08:00
Nicholas Dudfield
7d72dfe0be Updated freeze tests:
* Always run freeze tests (and  enforcement tests)
* book_offers filtering tests are broken
2014-11-25 11:46:34 -08:00
Mark Travis
02529a0fc2 SHAMapStore Online Delete (RIPD-415):
Makes rippled configurable to support deletion of all data in its key-value
store (nodestore) and ledger and transaction SQLite databases based on
validated ledger sequence numbers. All records from a specified ledger
and forward shall remain available in the key-value store and SQLite, and
all data prior to that specific ledger may be deleted.

Additionally, the administrator may require that an RPC command be
executed to enable deletion. This is to align data deletion with local
policy.
2014-11-25 11:44:02 -08:00
JoelKatz
b44974677e Cleanup some stray formatting left in logs 2014-11-21 17:13:13 -08:00
Vinnie Falco
d4fd5e4fce HTTP Handshaking for Peers on Universal Port (RIPD-446):
This introduces a considerable change in the way that peers handshake. Instead
of sending the TMHello protocol message, the peer making the connection (client
role) sends an HTTP Upgrade request along with some special headers. The peer
acting in the server role sends an HTTP response completing the upgrade and
transition to RTXP (Ripple Transaction Protocol, a.k.a. peer protocol). If the
server has no available slots, then it sends a 503 Service Unavailable HTTP
response with a JSON content-body containing IP addresses of other servers to
try. The information that was previously contained in the TMHello message is
now communicated in the HTTP request and HTTP response including the secure
cookie to prevent man in the middle attacks. This information is documented
in the overlay README.md file.

To prevent disruption on the network, the handshake feature is rolled out in
two parts. This is part 1, where new servents acting in the client role will
send the old style TMHello handshake, and new servents acting in the server
role can automatically detect and accept both the old style TMHello handshake,
or the HTTP request accordingly. This detection happens in the Server module,
which supports the universal port. An experimental .cfg setting allows clients
to instead send HTTP handshakes when establishing peer connections. When this
code has reached a significant fraction of the network, these clients will be
able to establish a connection to the Ripple network using HTTP handshakes.

These changes clean up the handling of the socket for peers. It fixes a long
standing bug in the graceful close sequence, where remaining data such as the
IP addresses of other servers to try, did not get sent. Redundant state
variables for the peer are removed and the treatment of completion handlers is
streamlined. The treatment of SSL short reads and secure shutdown is also fixed.

Logging for the peers in the overlay module are divided into two partitions:
"Peer" and "Protocol". The Peer partition records activity taking place on the
socket while the Protocol partition informs about RTXP specific actions such as
transaction relay, fetch packs, and consensus rounds. The severity on the log
partitions may be adjusted independently to diagnose problems. Every log
message for peers is prefixed with a small, unique integer id in brackets,
to accurately associate log messages with peers.

HTTP handshaking is the first step in implementing the Hub and Spoke feature,
which transforms the network from a homogeneous network where all peers are
the same, into a structured network where peers with above average capabilities
in their ability to process ledgers and transactions self-assemble to form a
backbone of high powered machines which in turn serve a much larger number of
'leaves' with lower capacities with a goal to improve the number of
transactions that may be retired over time.
2014-11-21 16:47:12 -08:00
Vinnie Falco
30123eaa4a Add WrappedSink:
This class puts a configured string prefix in front of
each line of Journal output.
2014-11-21 16:46:57 -08:00
Nik Bougalis
454ec97d51 Replace custom exceptions with std::runtime_error 2014-11-21 13:15:41 -08:00
Vinnie Falco
c2ac331e78 Fix unit_test suite matching with full names 2014-11-21 12:59:32 -08:00
Nik Bougalis
be4a35af11 Clarify SetAccount logic and clean up existing code 2014-11-21 12:59:32 -08:00
Tom Ritchford
445b29ad0d Fix RPC handlers to use the results of lookupLedger. 2014-11-21 12:59:32 -08:00
Vinnie Falco
64d0f7fffd Fix DecayingSample treatment of the window 2014-11-21 12:59:32 -08:00
Nik Bougalis
baf0d09455 Simplify the Beast fatal error reporting framework:
* Reduce interface to a single function which reports error details
* Remove unused functions
2014-11-21 12:59:32 -08:00
Vinnie Falco
08a81a0ab9 Tidy up the structure of sources in protocol/:
Split out and rename STValidation
Split out and rename STBlob
Split out and rename STAccount
Split out STPathSet
Split STVector256 and move UintTypes to protocol/
Rename to STBase
Rename to STLedgerEntry
Rename to SOTemplate
Rename to STTx
Remove obsolete AgedHistory
Remove types.h and add missing includes
Remove unnecessary includes in app.h
Remove unnecessary includes in app.h
Remove include app.h from app1.cpp
2014-11-20 20:15:29 -08:00
Nik Bougalis
31110c7fd9 Cleanup ripple::Ledger:
* Convert static member functions to free functions
* Adopt consistent naming convention
* De-inline code
2014-11-20 20:15:29 -08:00
Vinnie Falco
0e1dd92d9b Fix case where slot==nullptr in Overlay:
This changes the Overlay to correctly handle the case when nullptr is
returned by PeerFinder new_inbound_slot on a detected self-connection.
2014-11-20 20:15:29 -08:00
Vinnie Falco
a3204a4df7 Add http::chunk_encode:
This transforms a ConstBufferSequence into a new ConstBufferSequence whose
data is encoded according to the Content transfer encoding rules of RFC2616.
The implementation does not copy any memory.
2014-11-20 20:15:29 -08:00
Donovan Hide
2288ab48b9 Use asio signal handling in Application (RIPD-140):
* Use signal_set as cross platform way of handling SIGINT
* Remove polling on main thread for shutdown.
* Add extra logging for received signal.
* Clean up exit handling on error in setup routines.
* Reuse isStopped() from Stoppable for status (could be isStopping() instead).
* Ctrl-C should now work for standalone mode as well on Windows.

Also small fixes to Resolver:
* Add Resolver prefix to logging.
* Fix AsyncObject::removeReference() logic.
* Fix work remaining logic.
2014-11-20 20:15:29 -08:00
mDuo13
670401884c Improve the human-readable description of the tesSUCCESS code:
Transactions that return tesSUCCESS have only been accepted and
propagated on the Ripple network and should not be considered
final until they have been included in a validated ledger.
2014-11-20 20:14:04 -08:00
Yana
37181c341e Changed doc/rippled-example.cfg to specify default for ssl_verify 2014-11-14 11:19:42 -08:00
wltsmrz
be7e677448 Update integration tests for changes to ripple-lib account request API:
Account requests expect an object as first argument
2014-11-14 11:10:12 -08:00
Josh Juran
b2eeb49a45 Clean up CKey and RippleAddress (RIPD-672)
* Remove CKey dependency on RippleAddress
* Create RAII ec_key wrapper that hides EC_KEY and other OpenSSL details
* Move CKey member logic into free functions
* Delete CKey class
* Rename units that are no longer CKey-related
* Delete code that was unused
2014-11-14 11:10:12 -08:00
Vinnie Falco
9aa040d917 Accept generic arguments in ci_equal 2014-11-14 11:10:11 -08:00
Vinnie Falco
c2043a223b Tidy up split_commas function and use it in Server
Conflicts:
	src/ripple/server/impl/ServerHandlerImp.cpp
2014-11-14 11:10:11 -08:00
Vinnie Falco
f24e859f17 Construct Server after Overlay and WSDoors:
When the ServerHandler is constructed before the Overlay, an incoming
connection received after the server's listening ports have been opened
but before the Overlay object has been created causes a crash.
2014-11-14 11:10:11 -08:00
Vinnie Falco
737b33f9d1 Merge branch 'release' into develop 2014-11-14 10:56:45 -08:00
David Schwartz
00791d2151 Set version to 0.26.4-sp3 2014-11-11 16:33:52 -08:00
David Schwartz
b141598f9b Fix bugs in pathfinding with XRP as the source currency 2014-11-11 16:27:39 -08:00
Tom Ritchford
d1618d79b0 Fix pathfinding with multiple issuers for one currency (RIPD-618).
* Allow pathfinding requests where the starting currency may have
  multiple issuers.

* Cache paths over all issuers to avoid repeating work.

* Clear the ledger checkpoint in one retry case.

* Add an additional node at the front of paths when the starting issuer
  is not the source account.
2014-11-11 16:27:03 -08:00
Tom Ritchford
00c84dfe5c Clean up Pathfinder.
* Restrict to 80-columns and other style cleanups.
* Make pathfinding a free function and hide the class Pathfinder.
* Split off unrelated utility functions into separate files.
2014-11-11 16:26:38 -08:00
Vinnie Falco
95f31b98a8 Set version to 0.26.4-sp2 2014-11-11 14:22:37 -08:00
Miguel Portilla
10d74ed100 Fix account_lines, account_offers and book_offers result (RIPD-682):
The RPC account_lines and account_offers commands respond with the correct ledger info. account_offers, account_lines and book_offers allow admins unlimited size on the limit param. Specifying a negative value on limit clamps to the minimum value allowed. Incorrect types for limit are correctly reported in the result.
2014-11-11 14:21:49 -08:00
Vinnie Falco
8a7f612d5b Revert pathfinding changes:
* 5e7c527 Revert "Fix account_lines, account_offers and book_offers result (RIPD-682):"
* b3417ca Revert "Fix pathfinding with multiple issuers for one currency (RIPD-618)."
* 00db7f5 Revert "Clean up Pathfinder."
2014-11-11 14:21:40 -08:00
Tom Ritchford
0829ee9234 Add missing header needed for boost 1.57 compatibility. 2014-11-10 23:23:53 -05:00
Nik Bougalis
b22e33444b Make Stoppable unit tests manual 2014-11-10 23:23:53 -05:00
David Schwartz
d115a12cbe Remove dead TxQueue code 2014-11-10 23:23:53 -05:00
Nik Bougalis
b7b744de94 Remove sole use of beast::MurmurHash 2014-11-10 15:00:20 -08:00
Nik Bougalis
68e46e406a Remove MurmurHash from Beast 2014-11-10 14:00:54 -08:00
Miguel Portilla
a46ae4efec Set version to 0.26.4-sp1 2014-11-10 16:25:45 -05:00
Miguel Portilla
62777a794e Fix account_lines, account_offers and book_offers result (RIPD-682):
The RPC account_lines and account_offers commands respond with the correct ledger info. account_offers, account_lines and book_offers allow admins unlimited size on the limit param. Specifying a negative value on limit clamps to the minimum value allowed. Incorrect types for limit are correctly reported in the result.
2014-11-10 16:25:14 -05:00
Tom Ritchford
329a969761 Remove unused RPCServer. 2014-11-10 12:53:21 -08:00
Vinnie Falco
30170bc394 Add short_read manual unit test:
This manual unit test explores the outcomes of shutting down
SSL stream connections at various point during a session.
2014-11-10 12:52:57 -08:00
Vinnie Falco
f193302e15 Add WrappedSink 2014-11-10 12:52:57 -08:00
Vinnie Falco
7c4870d641 Add operator<< for basic_streambuf 2014-11-10 12:52:43 -08:00
Vinnie Falco
8b84a76d5d Make ci_equal a function 2014-11-10 12:52:42 -08:00
Vinnie Falco
a4cd761372 Add rfc2616::parse_csv 2014-11-10 12:52:42 -08:00
Miguel Portilla
63d2cfd6ba Fix account_lines, account_offers and book_offers result (RIPD-682):
The RPC account_lines and account_offers commands respond with the correct
ledger info. account_offers, account_lines and book_offers allow admins
unlimited size on the limit param. Specifying a negative value on limit clamps
to the minimum value allowed. Incorrect types for limit are correctly reported
in the result.
2014-11-10 12:46:36 -08:00
Tom Ritchford
bb44bdd047 Fix pathfinding with multiple issuers for one currency (RIPD-618).
* Allow pathfinding requests where the starting currency may have
  multiple issuers.

* Cache paths over all issuers to avoid repeating work.

* Clear the ledger checkpoint in one retry case.

* Add an additional node at the front of paths when the starting issuer
  is not the source account.
2014-11-10 12:07:57 -05:00
Tom Ritchford
6904e66384 Clean up Pathfinder.
* Restrict to 80-columns and other style cleanups.
* Make pathfinding a free function and hide the class Pathfinder.
* Split off unrelated utility functions into separate files.
2014-11-10 12:06:49 -05:00
Vinnie Falco
fbffe2367e Fix weak_fn unit test. 2014-11-09 20:27:05 -08:00
Vinnie Falco
e442a2846d Overlay improvements and bug fixes:
PeerImp::detach had a default argument graceful=true which did not
correctly close the socket and cause the Overlay to often hang on exit.
The logging for Overlay and Peers has been reworked. All the socket activity
is logged to Peers while protocol activity goes to Protocol. Every log line
is prefixed by a small integer ID unique to the connection.
* Removed graceful PeerImp::detach option
* Peer and Protocol log message handle respective types of logging
* Log messages prefixed with peer unique integer
* Prevent call to timer ancel from throwing an exception
2014-11-08 14:39:46 -08:00
Vinnie Falco
f6985586ea Better logging when opening Server ports. 2014-11-08 14:36:45 -08:00
Vinnie Falco
2bae5b0959 Throw if rippled.cfg is missing a [server] section 2014-11-08 14:36:45 -08:00
Vinnie Falco
1e58809fcc Remove obsolete get_pointer 2014-11-08 14:36:44 -08:00
Vinnie Falco
6b1d213cc2 Add weak_fn 2014-11-08 14:36:44 -08:00
David Schwartz
42bec13a83 Add missing include needed for std::bad_cast in LexicalCast.h 2014-11-07 15:23:43 -08:00
Vinnie Falco
4415a179b3 Update freeze test for moved TxFlags.h 2014-11-07 14:12:43 -08:00
Vinnie Falco
5d42604efd Refactor the structure of source files:
* New src/ripple/crypto and src/ripple/protocol directories
* Merged src/ripple/common into src/ripple/basics
* Move resource/api files up a level
* Add headers for "include what you use"
* Normalized include guards
* Renamed to JsonFields.h
* Remove obsolete files
* Remove net.h unity header
* Remove resource.h unity header
* Removed some deprecated unity includes
2014-11-07 13:40:43 -08:00
Vinnie Falco
b134b7d3f6 Add missing includes. 2014-11-07 12:24:02 -08:00
Vinnie Falco
788219fe05 Adjust SSL context generation for Server:
The creation of self-signed certificates slows down the command
line client when launched repeatedly during unit test.
* Contexts are no longer generated for the command line client
* A port with no secure protocols generates an empty context
2014-11-07 06:13:56 -08:00
Tom Ritchford
9a7f66cfe9 Fix compilation errors in RPC/RipplePathFind.cpp 2014-11-06 21:58:13 -05:00
Tom Ritchford
daa4d16e61 Remove unused isXRP(Issue) function. 2014-11-06 20:17:13 -05:00
Tom Ritchford
cf05f87795 Fix pathfinding with multiple issuers for one currency (RIPD-618).
* Allow pathfinding requests where the starting currency may have
  multiple issuers.

* Cache paths over all issuers to avoid repeating work.

* Clear the ledger checkpoint in one retry case.

* Add an additional node at the front of paths when the starting issuer
  is not the source account.
2014-11-06 20:14:01 -05:00
Tom Ritchford
c2f2f83b7c Clean up Pathfinder.
* Restrict to 80-columns and other style cleanups.
* Make pathfinding a free function and hide the class Pathfinder.
* Split off unrelated utility functions into separate files.

Conflicts:
	src/ripple/rpc/handlers/RipplePathFind.cpp
2014-11-06 16:58:10 -08:00
Tom Ritchford
b30b2a523f Fix public member names of RPC::Context.
Conflicts:
	src/ripple/rpc/handlers/AccountTx.cpp
	src/ripple/rpc/handlers/AccountTxOld.cpp
	src/ripple/rpc/handlers/Ledger.cpp
	src/ripple/rpc/handlers/LedgerData.cpp
	src/ripple/rpc/handlers/RipplePathFind.cpp
	src/ripple/rpc/handlers/ServerInfo.cpp
	src/ripple/rpc/handlers/ServerState.cpp
	src/ripple/rpc/handlers/Submit.cpp
	src/ripple/rpc/handlers/Subscribe.cpp
	src/ripple/rpc/handlers/TxHistory.cpp
	src/ripple/rpc/handlers/Unsubscribe.cpp
	src/ripple/rpc/impl/Context.h
2014-11-06 16:55:20 -08:00
Nicholas Dudfield
150a3810a8 Update npm test rippled.cfg to use [server]:
The test now generates a configuration file with the new
configuration sections define by the Universal Port feature.
2014-11-06 16:10:00 -08:00
Vinnie Falco
ac0eaa912b Universal Port (RIPD-160):
This changes the behavior and configuration specification of the listening
ports that rippled uses to accept incoming connections for the supported
protocols: peer (Peer Protocol), http (JSON-RPC over HTTP), https (JSON-RPC)
over HTTPS, ws (Websockets Clients), and wss (Secure Websockets Clients).
Each listening port is now capable of handshaking in multiple protocols
specified in the configuration file (subject to some restrictions). Each
port can be configured to provide its own SSL certificate, or to use a
self-signed certificate. Ports can be configured to share settings, this
allows multiple ports to use the same certificate or values. The list of
ports is dynamic, administrators can open as few or as many ports as they
like. Authentication settings such as user/password or admin user/admin
password (for administrative commands on RPC or Websockets interfaces) can
also be specified per-port.

As the configuration file has changed significantly, administrators will
need to update their ripple.cfg files and carefully review the documentation
and new settings.

Changes:

* rippled-example.cfg updated with documentation and new example settings:
  All obsolete websocket, rpc, and peer configuration sections have been
  removed, the documentation updated, and a new documented set of example
  settings added.

* HTTP::Writer abstraction for sending HTTP server requests and responses
* HTTP::Handler handler improvements to support Universal Port
* HTTP::Handler handler supports legacy Peer protocol handshakes
* HTTP::Port uses shared_ptr<boost::asio::ssl::context>
* HTTP::PeerImp and Overlay use ssl_bundle to support Universal Port
* New JsonWriter to stream message and body through HTTP server
* ServerHandler refactored to support Universal Port and legacy peers
* ServerHandler Setup struct updated for Universal Port
* Refactor some PeerFinder members
* WSDoor and Websocket code stores and uses the HTTP::Port configuration
* Websocket autotls class receives the current secure/plain SSL setting
* Remove PeerDoor and obsolete Overlay peer accept code
* Remove obsolete RPCDoor and synchronous RPC handling code
* Remove other obsolete classes, types, and files
* Command line tool uses ServerHandler Setup for port and authorization info
* Fix handling of admin_user, admin_password in administrative commands
* Fix adminRole to check credentials for Universal Port
* Updated Overlay README.md

* Overlay sends IP:port redirects on HTTP Upgrade peer connection requests:
  Incoming peers who handshake using the HTTP Upgrade mechanism don't get
  a slot, and always get HTTP Status 503 redirect containing a JSON
  content-body with a set of alternate IP and port addresses to try, learned
  from PeerFinder. A future commit related to the Hub and Spoke feature will
  change the response to grant the peer a slot when there are peer slots
  available.

* HTTP responses to outgoing Peer connect requests parse redirect IP:ports:
  When the [overlay] configuration section (which is experimental) has
  http_handshake = 1, HTTP redirect responses will have the JSON content-body
  parsed to obtain the redirect IP:port addresses.

* Use a single io_service for HTTP::Server and Overlay:
  This is necessary to allow HTTP::Server to pass sockets to and from Overlay
  and eventually Websockets. Unfortunately Websockets is not so easily changed
  to use an externally provided io_service. This will be addressed in a future
  commit, and is one step necessary ease the restriction on ports configured
  to offer Websocket protocols in the .cfg file.
2014-11-06 16:10:00 -08:00
Vinnie Falco
e37d4043f6 Add missing includes to make headers compile separately 2014-11-03 16:40:57 -08:00
Vinnie Falco
d073425b44 Improved beast::http::message:
* Add headers::erase
* Set http::message version with std::pair
* Use std::pair for headers::value_type
2014-11-03 16:40:57 -08:00
Nicholas Dudfield
825b18cf71 Add bin/stop-test.js shutdown testing script:
This script launches rippled repeatedly and then issues a stop command
after a variable amount of time. This is to test the shutdown of the
application and catch errors.
2014-11-03 16:31:21 -08:00
Vinnie Falco
549ad3204f Fix race conditions closing HTTP I/O objects:
This fixes a case where stop can sometimes skip calling close on some
I/O objects or crash in a rare circumstance where a connection is in the
process of being torn down at the exact time the server is stopped. When
the acceptor receives errors, it logs the error and continues listening
instead of stopping.
2014-11-03 14:11:06 -08:00
Vinnie Falco
35f9499b67 Fix Overlay stop on exit:
The stop sequence for Overlay had a race condition where autoconnect could
be called after close_all, resulting in a hang on exit. This resolves the
problem by putting the close and timer operations on a strand:
* Rename some Overlay members
* Put close on strand and tidy up members
* Use completion handler instead of coroutine for timer
* Use App io_service in PeerFinder
2014-11-03 14:11:05 -08:00
Vinnie Falco
db82c35c17 Remove spurious assert in ResolverAsioImpl 2014-11-03 14:11:05 -08:00
Vinnie Falco
73c74f753c Change to the Application io_service:
* Simplified the implementation and removed class IoServicePool
* The io_service outlives the components of the Application
2014-11-03 14:11:05 -08:00
JoelKatz
a38fb2a5dc Clear the acquiring ledger when shutting down NetworkOPs:
This solves a circular destruction problem on exit.
2014-11-03 14:11:04 -08:00
Donovan Hide
38e99e01f9 Improve nodestore benchmarking:
* Use more succinct while loops on NodeFactory.
* Better formatting of multiple test results.
* Updated benchmarks.
* Use simpler and faster RNG to generate test data.
2014-11-02 07:16:08 -08:00
Donovan Hide
a1f46e84b8 Add new RocksDBQuickFactory for benchmarking:
This new factory is intended for benchmarking against the existing RocksDBFactory and has the following differences.
* Does not use BatchWriter
* Disables WAL for writes to memtable
* Uses a hash index in blocks
* Uses RocksDB OptimizeFor… functions
See Benchmarks.md for further discussion of some of the issues raised by investigation of RocksDB performance.
2014-11-01 07:12:09 -07:00
Donovan Hide
6540804571 Add repeatable NodeStore timing benchmark:
The timing test is changed to overcome possible file buffer cache effects by creating different read access patterns. The unittest-arg command line arguments allow running the benchmarks against any of the available backends and altering the parameters passed in the same format as rippled.cfg. The num_objects parameter permits variation of the number of key/values inserted. The data is random but matches reasonably well the values that rippled might generate.
2014-11-01 07:12:08 -07:00
Howard Hinnant
ffe6707595 Refactor Stoppable:
The Stoppable interface aids in the enforcement of invariants needed to
successful start and stop a multi-threaded application composed of classes
that depend on each other in complex ways.
* Test written to confirm the current behavior.
* Comments updated to reflect the current behavior.
* Public API reduced to what is currently in use.
* Protected data members made private.
* volatile bool members changed to std::atomic<bool>.
* std::atomic<int> members changed to std::atomic<bool>.
* Name storage uses std::string
2014-10-31 21:29:16 -07:00
Tom Ritchford
9b21740c9f Delete temporary directories at the end of tests (RIPD-460). 2014-10-31 21:21:54 -07:00
Tom Ritchford
bd12e2ab95 New class TempDirectory in UnitTestUtilities. 2014-10-31 21:21:54 -07:00
Donovan Hide
bffb5ef8b4 Avoid zero initialization of Blob:
This seemed to improve the performance of the copy, although there did seem to be some byte by byte copying still present. Further investigation recommended.
2014-10-31 20:12:39 -07:00
Donovan Hide
e4c9822d78 Enable processor-specific optimizations when available:
The SConstruct is modified to enable processor specific optimizations on clang and gcc toolchains. This improves the performance of RocksDB's CRC function. It might also enable other used libraries that are in the codebase now or in the future to apply cpu-specific optimisations. The mtune option ensures that a binary compiled on one machine will function on another,
2014-10-31 20:12:39 -07:00
Vinnie Falco
73187d8832 Remove obsolete multitls and proxy websocket features 2014-10-31 15:15:40 -07:00
Vinnie Falco
8101154d5e Remove obsolete websocket PROXY port 2014-10-31 15:15:40 -07:00
Vinnie Falco
c02937fd6f Remove obsolete sections from rippled-example.cfg:
* peer_port_proxy is obsolete since the MultiSocket was removed.
* peer_ssl_cipher_list has no effect, SSL ciphers are hard coded for security.
2014-10-31 15:15:40 -07:00
Vinnie Falco
3430be4075 Add PeerFinder onRedirects function 2014-10-31 13:27:55 -07:00
Vinnie Falco
3f2b6f771f Add streambuf to_string function 2014-10-31 13:27:38 -07:00
Vinnie Falco
6e39b49cc2 Add Json::stream to write Value to a Streambuf 2014-10-31 13:27:33 -07:00
Vinnie Falco
71c34ed4e0 Remove unused ErrorReply function 2014-10-31 13:25:54 -07:00
Vinnie Falco
477178675c Fix parseIniFile for duplicate sections 2014-10-31 13:25:30 -07:00
Vinnie Falco
dbdf68b248 Refactor HTTP::Server to support Universal Port:
These changes are necessary to support the Universal port feature. Synopsis:

* Persist HTTP peer io_service::work lifetime:
This simplification eliminates any potential for bugs caused by incorrect
lifetime management of the io_service::work object.

* Restructure Door to prevent data races, and handle clean exit:
The Server, Door, Door::detector, and Peer objects work together to
correctly implement graceful stop and destructors that block until
all child objects have been destroyed.

Cleanups:
* De-pimpl HTTP::Server
* Rename ServerImpl data members
* Tidy up HTTP::Port interface
2014-10-30 16:02:19 -07:00
Vinnie Falco
2fd139b307 Refactor Overlay and add [overlay] config section (experimental):
These changes prepare Overlay for the Universal Port and Hub and Spoke
features.

* Add [overlay configuration section:
The [overlay] section uses the new BasicConfig interface that
supports key-value pairs in the section. Some exposition is added to the
example cfg file. The new settings for overlay are related to the Hub and
Spoke feature which is currently in development. Production servers should
not set these configuration options, they are clearly marked experimental
in the example cfg file.

Other changes:
* Use _MSC_VER to detect Visual Studio
* Use ssl_bundle in Overlay::Peer
* Use shared_ptr to SSL context in Overlay:
* Removed undocumented PEER_SSL_CIPHER_LIST configuration setting
* Add Section::name: The Section object now stores its name for better diagnostic messages.
2014-10-30 13:55:01 -07:00
Vinnie Falco
a6c2657062 Add shared_ptr<boost::asio::ssl::context> to ssl_bundle:
This gives the ssl_bundle shared ownership of the underlying ssl context
so that ownership of the bundle may be transferred to other classes without
introduce lifetime issues.
2014-10-30 13:55:00 -07:00
Vinnie Falco
78a0bc0e2c Make streambuf buffers_type iterators default constructible 2014-10-30 13:55:00 -07:00
Edward Hennis
d7116d6867 Enable std::array overloads for boost::asio on clang:
* Remove Boost config option from beast config.
* Define from compiler, or let Boost figure out itself.
2014-10-30 13:55:00 -07:00
Josh Juran
edc15b9fa2 Use a self-signed certificate for peers (RIPD-108):
Generate a new RSA key pair and a self-signed X.509v3 certificate to use
with SSL connections to rippled peers.  New credentials are created each
startup.
2014-10-30 13:54:49 -07:00
Josh Juran
93d4b73b2f RippleSSLContext: Add openssl wrappers 2014-10-30 10:52:37 -07:00
Vinnie Falco
8e3849e591 Create Ripple SSL contexts using std::make_shared. 2014-10-30 10:52:36 -07:00
Vinnie Falco
acaa1098f7 Separate beast::http::body from beast::http::message (RIPD-660):
This changes the http::message object to no longer contain a body. It modifies
the parser to store the body in a separate object, or to pass the body data
to a functor. This allows the body to be stored in more flexible ways. For
example, in HTTP responses the body can be generated procedurally instead
of being required to exist entirely in memory at once.
2014-10-29 19:23:53 -07:00
Vinnie Falco
c1a5e88752 Use beast::asio::streambuf in Overlay 2014-10-29 19:23:53 -07:00
Vinnie Falco
74b99014d2 Add beast::asio::basic_streambuf (RIPD-661):
This is class whose interface is identical to the boost::asio::basic_streambuf,
and uses an implementation that stores the data in multiple discontiguous
linear buffers, expanding and shrinking as needed.
2014-10-29 19:23:53 -07:00
Tom Ritchford
9cba944d21 Add Json::to_string:
This allows the declaration for FastWriter to be hidden and makes
conversion of Json::Value objects to strings a little less clunky.
2014-10-29 19:23:52 -07:00
Tom Ritchford
8c1c2f5d05 Eliminate a copy of the string returned by FastWriter 2014-10-29 19:22:44 -07:00
Tom Ritchford
bf0fa8c562 Add 'sample' npm test:
test/sample-test.js is the smallest possible npm test.
2014-10-28 10:59:59 -07:00
Donovan Hide
3e1fc9ba6c Update unit testing command line parser parameters:
A string passed by the '--unittest-arg' command line parameter is passed to
suites when unit tests run and can be used to customize test behavior.
* Add '--unittest-arg' command line argument
* Remove obsolete '--unittest-format' command line argument
2014-10-28 10:55:44 -07:00
Vinnie Falco
4ceba603e4 Improvements to beast::unit_test framework:
* Some runner member functions are now thread-safe.
* De-inline and tidy up declarations and definitions.
* arg() interface allows command lines to be passed to suites.
2014-10-28 10:41:10 -07:00
2349 changed files with 197933 additions and 118423 deletions

6
.gitignore vendored
View File

@@ -31,6 +31,7 @@ Release/*.*
tmp
# Ignore database directory.
db/
db/*.db
db/*.db-*
@@ -75,4 +76,7 @@ My Amplifier XE Results - RippleD
/out.txt
# Build Log
rippled-build.log
rippled-build.log
# Profiling data
gmon.out

View File

@@ -6,20 +6,10 @@ before_install:
- sudo apt-get update -qq
- sudo apt-get install -qq python-software-properties
- sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
- sudo add-apt-repository -y ppa:boost-latest/ppa
- sudo add-apt-repository -y ppa:afrank/boost
- sudo apt-get update -qq
- sudo apt-get install -qq g++-4.8
- sudo apt-get install -qq libboost1.55-all-dev
# We want debug symbols for boost as we install gdb later
- sudo apt-get install -qq libboost1.55-dbg
- | # Setup the BOOST_ROOT
export BOOST_ROOT=$HOME/boost_root
mkdir -p $BOOST_ROOT/stage
ln -s /usr/lib/x86_64-linux-gnu $BOOST_ROOT/stage/lib
ln -s /usr/include/boost $BOOST_ROOT/boost
- | # Try to patch boost
sudo patch /usr/include/boost/bimap/detail/debug/static_error.hpp Builds/travis/static_error.boost.patch
sudo patch /usr/include/boost/config/compiler/clang.hpp Builds/travis/clang.boost.patch
- sudo apt-get install -qq libboost1.57-all-dev
- sudo apt-get install -qq mlocate
- sudo updatedb
- sudo locate libboost | grep /lib | grep -e ".a$"
@@ -44,6 +34,9 @@ before_install:
script:
# Set so any failing command will abort the build
- set -e
# Make sure vcxproj is up to date
- scons vcxproj
- git diff --exit-code
# $CC will be either `clang` or `gcc` (If only we could do -j12 ;)
- scons $CC.debug
# We can be sure we're using the build/$CC.debug variant (-f so never err)

View File

@@ -0,0 +1,23 @@
FROM ubuntu
MAINTAINER Torrie Fischer <torrie@ripple.com>
RUN apt-get update -qq &&\
apt-get install -qq software-properties-common &&\
apt-add-repository -y ppa:ubuntu-toolchain-r/test &&\
apt-add-repository -y ppa:afrank/boost &&\
apt-get update -qq
RUN apt-get purge -qq libboost1.48-dev &&\
apt-get install -qq libprotobuf8 libboost1.57-all-dev
RUN mkdir -p /srv/rippled/data
VOLUME /srv/rippled/data/
ENTRYPOINT ["/srv/rippled/bin/rippled"]
CMD ["--conf", "/srv/rippled/data/rippled.cfg"]
EXPOSE 51235/udp
EXPOSE 5005/tcp
ADD ./rippled.cfg /srv/rippled/data/rippled.cfg
ADD ./rippled /srv/rippled/bin/

180
Builds/Test.py Executable file
View File

@@ -0,0 +1,180 @@
#!/usr/bin/env python
# This file is part of rippled: https://github.com/ripple/rippled
# Copyright (c) 2012 - 2015 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.
"""
Invocation:
./Builds/Test.py - builds and tests all configurations
#
# The build must succeed without shell aliases for this to work.
#
# Common problems:
# 1) Boost not found. Solution: export BOOST_ROOT=[path to boost folder]
# 2) OpenSSL not found. Solution: export OPENSSL_ROOT=[path to OpenSSL folder]
# 3) scons is an alias. Solution: Create a script named "scons" somewhere in
# your $PATH (eg. ~/bin/scons will often work).
# #!/bin/sh
# python /C/Python27/Scripts/scons.py "${@}"
"""
from __future__ import absolute_import, division, print_function, unicode_literals
import argparse
import itertools
import os
import platform
import re
import subprocess
import sys
IS_WINDOWS = platform.system().lower() == 'windows'
if IS_WINDOWS:
BINARY_RE = re.compile(r'build\\([^\\]+)\\rippled.exe')
else:
BINARY_RE = re.compile(r'build/([^/]+)/rippled')
ALL_TARGETS = ['debug', 'release']
parser = argparse.ArgumentParser(
description='Test.py - run ripple tests'
)
parser.add_argument(
'--all', '-a',
action='store_true',
help='Build all configurations.',
)
parser.add_argument(
'--keep_going', '-k',
action='store_true',
help='Keep going after one configuration has failed.',
)
parser.add_argument(
'--silent', '-s',
action='store_true',
help='Silence all messages except errors',
)
parser.add_argument(
'--verbose', '-v',
action='store_true',
help=('Report more information about which commands are executed and the '
'results.'),
)
parser.add_argument(
'--test', '-t',
default='',
help='Add a prefix for unit tests',
)
parser.add_argument(
'scons_args',
default=(),
nargs='*'
)
ARGS = parser.parse_args()
def shell(*cmd, **kwds):
"Execute a shell command and return the output."
silent = kwds.pop('silent', ARGS.silent)
verbose = not silent and kwds.pop('verbose', ARGS.verbose)
if verbose:
print('$', ' '.join(cmd))
kwds['shell'] = IS_WINDOWS
process = subprocess.Popen(
cmd,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
**kwds)
lines = []
count = 0
for line in process.stdout:
lines.append(line)
if verbose:
print(line, end='')
elif not silent:
count += 1
if count >= 80:
print()
count = 0
else:
print('.', end='')
if not verbose and count:
print()
process.wait()
return process.returncode, lines
if __name__ == '__main__':
args = list(ARGS.scons_args)
if ARGS.all:
for a in ALL_TARGETS:
if a not in args:
args.append(a)
print('Building:', *(args or ['(default)']))
# Build everything.
resultcode, lines = shell('scons', *args)
if resultcode:
print('Build FAILED:')
if not ARGS.verbose:
print(*lines, sep='')
exit(1)
# Now extract the executable names and corresponding targets.
failed = []
_, lines = shell('scons', '-n', '--tree=derived', *args, silent=True)
for line in lines:
match = BINARY_RE.search(line)
if match:
executable, target = match.group(0, 1)
print('Unit tests for', target)
testflag = '--unittest'
if ARGS.test:
testflag += ('=' + ARGS.test)
resultcode, lines = shell(executable, testflag)
if resultcode:
print('ERROR:', *lines, sep='')
failed.append([target, 'unittest'])
if not ARGS.keep_going:
break
ARGS.verbose and print(*lines, sep='')
print('npm tests for', target)
resultcode, lines = shell('npm', 'test', '--rippled=' + executable)
if resultcode:
print('ERROR:\n', *lines, sep='')
failed.append([target, 'npm'])
if not ARGS.keep_going:
break
else:
ARGS.verbose and print(*lines, sep='')
if failed:
print('FAILED:', *(':'.join(f) for f in failed))
exit(1)
else:
print('Success')

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,24 +1,26 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Express 2013 for Windows Desktop
VisualStudioVersion = 12.0.30110.0
VisualStudioVersion = 12.0.31101.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RippleD", "RippleD.vcxproj", "{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
debug.classic|x64 = debug.classic|x64
debug|x64 = debug|x64
release.classic|x64 = release.classic|x64
release|x64 = release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}.Debug|Win32.ActiveCfg = debug|x64
{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}.Debug|x64.ActiveCfg = debug|x64
{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}.Debug|x64.Build.0 = debug|x64
{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}.Release|Win32.ActiveCfg = release|x64
{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}.Release|x64.ActiveCfg = release|x64
{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}.Release|x64.Build.0 = release|x64
{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}.debug.classic|x64.ActiveCfg = debug.classic|x64
{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}.debug.classic|x64.Build.0 = debug.classic|x64
{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}.debug|x64.ActiveCfg = debug|x64
{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}.debug|x64.Build.0 = debug|x64
{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}.release.classic|x64.ActiveCfg = release.classic|x64
{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}.release.classic|x64.Build.0 = release.classic|x64
{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}.release|x64.ActiveCfg = release|x64
{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}.release|x64.Build.0 = release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@@ -1,5 +1,5 @@
Name: rippled
Version: 0.26.4
Version: 0.28.1-rc1
Release: 1%{?dist}
Summary: Ripple peer-to-peer network daemon
@@ -50,4 +50,3 @@ rm -rf %{buildroot}
/usr/bin/rippled
/usr/share/rippled/LICENSE
/etc/rippled/rippled-example.cfg

View File

@@ -1,3 +1,77 @@
![Ripple](/images/ripple.png)
#The Worlds Fastest and Most Secure Payment System
**What is Ripple?**
Ripple is the open-source, distributed payment protocol that enables instant
payments with low fees, no chargebacks, and currency flexibility (for example
dollars, yen, euros, bitcoins, or even loyalty points). Businesses of any size
can easily build payment solutions such as banking or remittance apps, and
accelerate the movement of money. Ripple enables the world to move value the
way it moves information on the Internet.
![Ripple Network](images/network.png)
**What is a Gateway?**
Ripple works with gateways: independent businesses which hold customer
deposits in various currencies such as U.S. dollars (USD) or Euros (EUR),
in exchange for providing cryptographically-signed issuances that users can
send and trade with one another in seconds on the Ripple network. Within the
protocol, exchanges between multiple currencies can occur atomically without
any central authority to monitor them. Later, customers can withdraw their
Ripple balances from the gateways that created those issuances.
**How do Ripple payments work?**
A sender specifies the amount and currency the recipient should receive and
Ripple automatically converts the senders available currencies using the
distributed order books integrated into the Ripple protocol. Independent third
parties acting as market makers provide liquidity in these order books.
Ripple uses a pathfinding algorithm that considers currency pairs when
converting from the source to the destination currency. This algorithm searches
for a series of currency swaps that gives the user the lowest cost. Since
anyone can participate as a market maker, market forces drive fees to the
lowest practical level.
**What can you do with Ripple?**
The protocol is entirely open-source and the networks shared ledger is public
information, so no central authority prevents anyone from participating. Anyone
can become a market maker, create a wallet or a gateway, or monitor network
behavior. Competition drives down spreads and fees, making the network useful
to everyone.
###Key Protocol Features
1. XRP is Ripples native [cryptocurrency]
(http://en.wikipedia.org/wiki/Cryptocurrency) with a fixed supply that
decreases slowly over time, with no mining. XRP acts as a bridge currency, and
pays for transaction fees that protect the network against spam.
![XRP as a bridge currency](/images/vehicle_currency.png)
2. Pathfinding discovers cheap and efficient payment paths through multiple
[order books](https://www.ripplecharts.com) allowing anyone to [trade](https://www.rippletrade.com) anything. When two accounts arent linked by relationships of trust, the Ripple pathfinding engine considers intermediate links and order books to produce a set of possible paths the transaction can take. When the payment is processed, the liquidity along these paths is iteratively consumed in best-first order.
![Pathfinding from Dollars to Euro](/images/pathfinding.png)
3. [Consensus](https://www.youtube.com/watch?v=pj1QVb1vlC0) confirms
transactions in an atomic fashion, without mining, ensuring efficient use of
resources.
[transact]: https://ripple.com/files/ripple-FIs.pdf
[build]: https://ripple.com/build/
[transact.png]: /images/transact.png
[build.png]: /images/build.png
[contribute.png]: /images/contribute.png
###Join The Ripple Community
|![Transact][transact.png]|![Build][build.png]|![Contribute][contribute.png]|
|:-----------------------:|:-----------------:|:---------------------------:|
|[Transact on the fastest payment infrastructure][transact]|[Build Imaginative Apps][build]|Contribute to the Ripple Protocol Implementation|
#rippled - Ripple P2P server
##[![Build Status](https://travis-ci.org/ripple/rippled.png?branch=develop)](https://travis-ci.org/ripple/rippled)
@@ -10,6 +84,9 @@ This is the repository for Ripple's `rippled`, reference P2P server.
###Setup instructions:
* https://ripple.com/wiki/Rippled_setup_instructions
###Issues
* https://ripplelabs.atlassian.net/browse/RIPD
### Repository Contents
#### ./bin
@@ -37,5 +114,9 @@ Ripple is open source and permissively licensed under the ISC license. See the
LICENSE file for more details.
###For more information:
* https://ripple.com
* https://ripple.com/wiki
* Ripple Wiki - https://ripple.com/wiki/
* Ripple Primer - https://ripple.com/ripple_primer.pdf
* Ripple Primer (Market Making) - https://ripple.com/ripple-mm.pdf
* Ripple Gateway Primer - https://ripple.com/ripple-gateways.pdf
* Consensus - https://wiki.ripple.com/Consensus

View File

@@ -11,14 +11,17 @@
all All available variants
debug All available debug variants
release All available release variants
profile All available profile variants
clang All clang variants
clang.debug clang debug variant
clang.release clang release variant
clang.profile clang profile variant
gcc All gcc variants
gcc.debug gcc debug variant
gcc.release gcc release variant
gcc.profile gcc profile variant
msvc All msvc variants
msvc.debug MSVC debug variant
@@ -26,10 +29,37 @@
vcxproj Generate Visual Studio 2013 project file
count Show line count metrics
Any individual target can also have ".nounity" appended for a classic,
non unity build. Example:
scons gcc.debug.nounity
If the clang toolchain is detected, then the default target will use it, else
the gcc toolchain will be used. On Windows environments, the MSVC toolchain is
also detected.
The following environment variables modify the build environment:
CLANG_CC
CLANG_CXX
CLANG_LINK
If set, a clang toolchain will be used. These must all be set together.
GNU_CC
GNU_CXX
GNU_LINK
If set, a gcc toolchain will be used (unless a clang toolchain is
detected first). These must all be set together.
CXX
If set, used to detect a toolchain.
BOOST_ROOT
Path to the boost directory.
OPENSSL_ROOT
Path to the openssl directory.
'''
#
'''
@@ -83,6 +113,29 @@ def check_openssl():
(CHECK_LINE, CHECK_COMMAND))
def set_implicit_cache():
'''Use implicit_cache on some targets to improve build times.
By default, scons scans each file for include dependecies. The implicit
cache flag lets you cache these dependencies for later builds, and will
only rescan files that change.
Failure cases are:
1) If the include search paths are changed (i.e. CPPPATH), then a file
may not be rebuilt.
2) If a same-named file has been added to a directory that is earlier in
the search path than the directory in which the file was found.
Turn on if this build is for a specific debug target (i.e. clang.debug)
If one of the failure cases applies, you can force a rescan of dependencies
using the command line option `--implicit-deps-changed`
'''
if len(COMMAND_LINE_TARGETS) == 1:
s = COMMAND_LINE_TARGETS[0].split('.')
if len(s) > 1 and 'debug' in s:
SetOption('implicit_cache', 1)
def import_environ(env):
'''Imports environment settings into the construction environment'''
def set(keys):
@@ -199,7 +252,11 @@ def config_base(env):
)
check_openssl()
env.Append(CPPDEFINES=['OPENSSL_NO_SSL2'])
env.Append(CPPDEFINES=[
'OPENSSL_NO_SSL2'
,'DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER'
,{'HAVE_USLEEP' : '1'}
])
try:
BOOST_ROOT = os.path.normpath(os.environ['BOOST_ROOT'])
@@ -245,7 +302,7 @@ def config_env(toolchain, variant, env):
if variant == 'debug':
env.Append(CPPDEFINES=['DEBUG', '_DEBUG'])
elif variant == 'release':
elif variant == 'release' or variant == 'profile':
env.Append(CPPDEFINES=['NDEBUG'])
if toolchain in Split('clang gcc'):
@@ -263,14 +320,32 @@ def config_env(toolchain, variant, env):
'-g' # generate debug symbols
])
env.Append(LINKFLAGS=[
'-rdynamic',
'-g',
])
if variant == 'profile':
env.Append(CCFLAGS=[
'-p',
'-pg',
])
env.Append(LINKFLAGS=[
'-p',
'-pg',
])
if toolchain == 'clang':
env.Append(CCFLAGS=['-Wno-redeclared-class-member'])
env.Append(CPPDEFINES=['BOOST_ASIO_HAS_STD_ARRAY'])
env.Append(CXXFLAGS=[
'-frtti',
'-std=c++11',
'-Wno-invalid-offsetof'])
env.Append(CPPDEFINES=['_FILE_OFFSET_BITS=64'])
if Beast.system.osx:
env.Append(CPPDEFINES={
'BEAST_COMPILE_OBJECTIVE_CPP': 1,
@@ -298,11 +373,10 @@ def config_env(toolchain, variant, env):
'boost_program_options',
'boost_regex',
'boost_system',
'boost_thread'
]
# We prefer static libraries for boost
if env.get('BOOST_ROOT'):
# Need to add boost_thread. Not needed when dynamic linking is used.
boost_libs += ['boost_thread']
static_libs = ['%s/stage/lib/lib%s.a' % (env['BOOST_ROOT'], l) for
l in boost_libs]
if all(os.path.exists(f) for f in static_libs):
@@ -324,22 +398,12 @@ def config_env(toolchain, variant, env):
else:
env.Append(LIBS=['rt'])
env.Append(LINKFLAGS=[
'-rdynamic'
])
if variant == 'release':
env.Append(CCFLAGS=[
'-O3',
'-fno-strict-aliasing'
])
if toolchain != 'msvc':
git = Beast.Git(env)
if git.exists:
id = '%s+%s.%s' % (git.tags, git.user, git.branch)
env.Append(CPPDEFINES={'GIT_COMMIT_ID' : '\'"%s"\'' % id })
if toolchain == 'clang':
if Beast.system.osx:
env.Replace(CC='clang', CXX='clang++', LINK='clang++')
@@ -466,6 +530,7 @@ def config_env(toolchain, variant, env):
# Configure the base construction environment
root_dir = Dir('#').srcnode().get_abspath() # Path to this SConstruct file
build_dir = os.path.join('build')
base = Environment(
toolpath=[os.path.join ('src', 'beast', 'site_scons', 'site_tools')],
tools=['default', 'Protoc', 'VSProject'],
@@ -477,10 +542,14 @@ base.Append(CPPPATH=[
'src',
os.path.join('src', 'beast'),
os.path.join(build_dir, 'proto'),
os.path.join('src','soci','src'),
])
base.Decider('MD5-timestamp')
set_implicit_cache()
# Configure the toolchains, variants, default toolchain, and default target
variants = ['debug', 'release']
variants = ['debug', 'release', 'profile']
all_toolchains = ['clang', 'gcc', 'msvc']
if Beast.system.osx:
toolchains = ['clang']
@@ -501,6 +570,8 @@ else:
default_toolchain = 'clang'
else:
raise ValueError("Don't understand toolchains in " + str(toolchains))
default_tu_style = 'unity'
default_variant = 'release'
default_target = None
@@ -527,144 +598,273 @@ class ObjectBuilder(object):
if kwds:
env = env.Clone()
env.Prepend(**kwds)
path = UNITY_BUILD_DIRECTORY + filename
o = env.Object(Beast.variantFile(path, self.variant_dirs))
o = env.Object(Beast.variantFile(filename, self.variant_dirs))
self.objects.append(o)
def list_sources(base, suffixes):
def _iter(base):
for parent, dirs, files in os.walk(base):
files = [f for f in files if not f[0] == '.']
dirs[:] = [d for d in dirs if not d[0] == '.']
for path in files:
path = os.path.join(parent, path)
r = os.path.splitext(path)
if r[1] and r[1] in suffixes:
yield os.path.normpath(path)
return list(_iter(base))
def append_sources(result, *filenames, **kwds):
result.append([filenames, kwds])
def get_soci_sources(style):
result = []
cpp_path = [
'src/soci/src/core',
'src/sqlite', ]
append_sources(result,
'src/ripple/unity/soci.cpp',
CPPPATH=cpp_path)
if style == 'unity':
append_sources(result,
'src/ripple/unity/soci_ripple.cpp',
CPPPATH=cpp_path)
return result
def get_classic_sources():
result = []
append_sources(
result,
*list_sources('src/ripple/app', '.cpp'),
CPPPATH=[
'src/soci/src/core',
'src/sqlite']
)
append_sources(result, *list_sources('src/ripple/basics', '.cpp'))
append_sources(result, *list_sources('src/ripple/core', '.cpp'))
append_sources(result, *list_sources('src/ripple/crypto', '.cpp'))
append_sources(result, *list_sources('src/ripple/json', '.cpp'))
append_sources(result, *list_sources('src/ripple/legacy', '.cpp'))
append_sources(result, *list_sources('src/ripple/net', '.cpp'))
append_sources(result, *list_sources('src/ripple/overlay', '.cpp'))
append_sources(result, *list_sources('src/ripple/peerfinder', '.cpp'))
append_sources(result, *list_sources('src/ripple/protocol', '.cpp'))
append_sources(result, *list_sources('src/ripple/shamap', '.cpp'))
append_sources(
result,
*list_sources('src/ripple/nodestore', '.cpp'),
CPPPATH=[
'src/rocksdb2/include',
'src/snappy/snappy',
'src/snappy/config',
])
result += get_soci_sources('classic')
return result
def get_unity_sources():
result = []
append_sources(
result,
'src/ripple/unity/app.cpp',
'src/ripple/unity/app1.cpp',
'src/ripple/unity/app2.cpp',
'src/ripple/unity/app3.cpp',
'src/ripple/unity/app4.cpp',
'src/ripple/unity/app5.cpp',
'src/ripple/unity/app6.cpp',
'src/ripple/unity/app7.cpp',
'src/ripple/unity/app8.cpp',
'src/ripple/unity/app9.cpp',
'src/ripple/unity/core.cpp',
'src/ripple/unity/basics.cpp',
'src/ripple/unity/crypto.cpp',
'src/ripple/unity/net.cpp',
'src/ripple/unity/overlay.cpp',
'src/ripple/unity/peerfinder.cpp',
'src/ripple/unity/json.cpp',
'src/ripple/unity/protocol.cpp',
'src/ripple/unity/shamap.cpp',
'src/ripple/unity/legacy.cpp',
)
result += get_soci_sources('unity')
append_sources(
result,
'src/ripple/unity/nodestore.cpp',
CPPPATH=[
'src/rocksdb2/include',
'src/snappy/snappy',
'src/snappy/config',
])
return result
# Declare the targets
aliases = collections.defaultdict(list)
msvc_configs = []
for toolchain in all_toolchains:
for variant in variants:
# Configure this variant's construction environment
env = base.Clone()
config_env(toolchain, variant, env)
variant_name = '%s.%s' % (toolchain, variant)
variant_dir = os.path.join(build_dir, variant_name)
variant_dirs = {
os.path.join(variant_dir, 'src') :
'src',
os.path.join(variant_dir, 'proto') :
os.path.join (build_dir, 'proto'),
}
for dest, source in variant_dirs.iteritems():
env.VariantDir(dest, source, duplicate=0)
object_builder = ObjectBuilder(env, variant_dirs)
object_builder.add_source_files(
'app.cpp',
'app1.cpp',
'app2.cpp',
'app3.cpp',
'app4.cpp',
'app5.cpp',
'app6.cpp',
'app7.cpp',
'app8.cpp',
'app9.cpp',
'basics.cpp',
'beast.cpp',
'common.cpp',
'core.cpp',
'data.cpp',
'http.cpp',
'json.cpp',
'net.cpp',
'overlay.cpp',
'peerfinder.cpp',
'protobuf.cpp',
'ripple.proto.cpp',
'resource.cpp',
'rpcx.cpp',
'sitefiles.cpp',
'sslutil.cpp',
'types.cpp',
'validators.cpp',
'websocket.cpp',
)
object_builder.add_source_files(
'beastc.c',
CCFLAGS=['-Wno-array-bounds'])
def should_prepare_target(cl_target,
style, toolchain, variant):
if not cl_target:
# default target
return (style == default_tu_style and
toolchain == default_toolchain and
variant == default_variant)
if 'vcxproj' in cl_target:
return toolchain == 'msvc'
s = cl_target.split('.')
if style == 'unity' and 'nounity' in s:
return False
if len(s) == 1:
return ('all' in cl_target or
variant in cl_target or
toolchain in cl_target)
if len(s) == 2 or len(s) == 3:
return s[0] == toolchain and s[1] == variant
object_builder.add_source_files(
'nodestore.cpp',
CPPPATH=[
'src/leveldb/include',
#'src/hyperleveldb/include', # hyper
'src/rocksdb2/include',
]
)
return True # A target we don't know about, better prepare to build it
if 'gcc' in toolchain:
no_uninitialized_warning = {'CCFLAGS': ['-Wno-maybe-uninitialized']}
else:
no_uninitialized_warning = {}
object_builder.add_source_files(
'leveldb.cpp',
CPPPATH=[
'src/leveldb/',
'src/leveldb/include',
'src/snappy/snappy',
'src/snappy/config',
],
**no_uninitialized_warning
)
def should_prepare_targets(style, toolchain, variant):
if not COMMAND_LINE_TARGETS:
return should_prepare_target(None, style, toolchain, variant)
for t in COMMAND_LINE_TARGETS:
if should_prepare_target(t, style, toolchain, variant):
return True
object_builder.add_source_files(
'hyperleveldb.cpp',
CPPPATH=[
'src/hyperleveldb',
'src/snappy/snappy',
'src/snappy/config',
],
**no_uninitialized_warning
)
for tu_style in ['classic', 'unity']:
if tu_style == 'classic':
sources = get_classic_sources()
else:
sources = get_unity_sources()
for toolchain in all_toolchains:
for variant in variants:
if not should_prepare_targets(tu_style, toolchain, variant):
continue
if variant == 'profile' and toolchain == 'msvc':
continue
# Configure this variant's construction environment
env = base.Clone()
config_env(toolchain, variant, env)
variant_name = '%s.%s' % (toolchain, variant)
if tu_style == 'classic':
variant_name += '.nounity'
variant_dir = os.path.join(build_dir, variant_name)
variant_dirs = {
os.path.join(variant_dir, 'src') :
'src',
os.path.join(variant_dir, 'proto') :
os.path.join (build_dir, 'proto'),
}
for dest, source in variant_dirs.iteritems():
env.VariantDir(dest, source, duplicate=0)
object_builder.add_source_files(
'rocksdb.cpp',
CPPPATH=[
'src/rocksdb2',
'src/rocksdb2/include',
'src/snappy/snappy',
'src/snappy/config',
],
**no_uninitialized_warning
)
object_builder = ObjectBuilder(env, variant_dirs)
object_builder.add_source_files(
'snappy.cpp',
CCFLAGS=['-Wno-unused-function'],
CPPPATH=[
'src/snappy/snappy',
'src/snappy/config',
]
)
for s, k in sources:
object_builder.add_source_files(*s, **k)
if toolchain == "clang" and Beast.system.osx:
object_builder.add_source_files('beastobjc.mm')
git_commit_tag = {}
if toolchain != 'msvc':
git = Beast.Git(env)
if git.exists:
id = '%s+%s.%s' % (git.tags, git.user, git.branch)
git_commit_tag = {'CPPDEFINES':
{'GIT_COMMIT_ID' : '\'"%s"\'' % id }}
target = env.Program(
target=os.path.join(variant_dir, 'rippled'),
source=object_builder.objects
object_builder.add_source_files(
'src/ripple/unity/git_id.cpp',
**git_commit_tag)
object_builder.add_source_files(
'src/beast/beast/unity/hash_unity.cpp',
'src/ripple/unity/beast.cpp',
'src/ripple/unity/lz4.c',
'src/ripple/unity/protobuf.cpp',
'src/ripple/unity/ripple.proto.cpp',
'src/ripple/unity/resource.cpp',
'src/ripple/unity/rpcx.cpp',
'src/ripple/unity/server.cpp',
'src/ripple/unity/validators.cpp',
'src/ripple/unity/websocket02.cpp'
)
if toolchain == default_toolchain and variant == default_variant:
default_target = target
install_target = env.Install (build_dir, source=default_target)
env.Alias ('install', install_target)
env.Default (install_target)
aliases['all'].extend(install_target)
if toolchain == 'msvc':
config = env.VSProjectConfig(variant, 'x64', target, env)
msvc_configs.append(config)
if toolchain in toolchains:
aliases['all'].extend(target)
aliases[variant].extend(target)
aliases[toolchain].extend(target)
env.Alias(variant_name, target)
object_builder.add_source_files(
'src/ripple/unity/beastc.c',
CCFLAGS = ([] if toolchain == 'msvc' else ['-Wno-array-bounds']))
if 'gcc' in toolchain:
no_uninitialized_warning = {'CCFLAGS': ['-Wno-maybe-uninitialized']}
else:
no_uninitialized_warning = {}
object_builder.add_source_files(
'src/ripple/unity/ed25519.c',
CPPPATH=[
'src/ed25519-donna',
]
)
object_builder.add_source_files(
'src/ripple/unity/rocksdb.cpp',
CPPPATH=[
'src/rocksdb2',
'src/rocksdb2/include',
'src/snappy/snappy',
'src/snappy/config',
],
**no_uninitialized_warning
)
object_builder.add_source_files(
'src/ripple/unity/snappy.cpp',
CCFLAGS=([] if toolchain == 'msvc' else ['-Wno-unused-function']),
CPPPATH=[
'src/snappy/snappy',
'src/snappy/config',
]
)
object_builder.add_source_files(
'src/ripple/unity/websocket04.cpp',
CPPPATH='src/websocketpp',
)
if toolchain == "clang" and Beast.system.osx:
object_builder.add_source_files('src/ripple/unity/beastobjc.mm')
target = env.Program(
target=os.path.join(variant_dir, 'rippled'),
source=object_builder.objects
)
if tu_style == default_tu_style:
if toolchain == default_toolchain and (
variant == default_variant):
default_target = target
install_target = env.Install (build_dir, source=default_target)
env.Alias ('install', install_target)
env.Default (install_target)
aliases['all'].extend(install_target)
if toolchain == 'msvc':
config = env.VSProjectConfig(variant, 'x64', target, env)
msvc_configs.append(config)
if toolchain in toolchains:
aliases['all'].extend(target)
aliases[toolchain].extend(target)
elif toolchain == 'msvc':
config = env.VSProjectConfig(variant + ".classic", 'x64', target, env)
msvc_configs.append(config)
if toolchain in toolchains:
aliases[variant].extend(target)
env.Alias(variant_name, target)
for key, value in aliases.iteritems():
env.Alias(key, value)
@@ -675,3 +875,33 @@ vcxproj = base.VSProject(
VSPROJECT_ROOT_DIRS = ['src/beast', 'src', '.'],
VSPROJECT_CONFIGS = msvc_configs)
base.Alias('vcxproj', vcxproj)
#-------------------------------------------------------------------------------
# Adds a phony target to the environment that always builds
# See: http://www.scons.org/wiki/PhonyTargets
def PhonyTargets(env = None, **kw):
if not env: env = DefaultEnvironment()
for target, action in kw.items():
env.AlwaysBuild(env.Alias(target, [], action))
# Build the list of rippled source files that hold unit tests
def do_count(target, source, env):
def list_testfiles(base, suffixes):
def _iter(base):
for parent, _, files in os.walk(base):
for path in files:
path = os.path.join(parent, path)
r = os.path.splitext(path)
if r[1] in suffixes:
if r[0].endswith('.test'):
yield os.path.normpath(path)
return list(_iter(base))
testfiles = list_testfiles(os.path.join('src', 'ripple'), env.get('CPPSUFFIXES'))
lines = 0
for f in testfiles:
lines = lines + sum(1 for line in open(f))
print "Total unit test lines: %d" % lines
PhonyTargets(env, count = do_count)

77
appveyor.yml Normal file
View File

@@ -0,0 +1,77 @@
# Set environment variables.
environment:
PYTHON: C:/Python27-x64
# We bundle up protoc.exe and only the parts of boost and openssl we need so
# that it's a small download. We also use appveyor's free cache, avoiding fees
# downloading from S3 each time.
# TODO: script to create this package.
RIPPLED_DEPS_URL: https://s3-ap-northeast-1.amazonaws.com/history-replay/rippled_deps.zip
# Other dependencies we just download each time.
PIP_URL: https://bootstrap.pypa.io/get-pip.py
PYWIN32_URL: https://downloads.sourceforge.net/project/pywin32/pywin32/Build%20219/pywin32-219.win-amd64-py2.7.exe
# Scons honours these environment variables, setting the include/lib paths.
BOOST_ROOT: C:/rippled_deps/boost
OPENSSL_ROOT: C:/rippled_deps/openssl
# At the end of each successful build we cache this directory. It must be less
# than 100MB total compressed.
cache:
- "C:\\rippled_deps"
# This means we'll download a zip of the branch we want, rather than the full
# history.
shallow_clone: true
install:
# We want easy_install, python and protoc.exe on PATH.
- SET PATH=%PYTHON%;%PYTHON%/Scripts;C:/rippled_deps;%PATH%
# `ps` prefix means the command is executed by powershell.
- ps: Start-FileDownload $env:PIP_URL
- ps: Start-FileDownload $env:PYWIN32_URL
# Installing pip will install setuptools/easy_install.
- python get-pip.py
# Pip has some problems installing scons on windows so we use easy install.
- easy_install scons
# Scons has problems with parallel builds on windows without pywin32.
- easy_install pywin32-219.win-amd64-py2.7.exe
# (easy_install can do headless installs of .exe wizards)
# Download dependencies if appveyor didn't restore them from the cache.
# Use 7zip to unzip.
- ps: |
if (-not(Test-Path 'C:/rippled_deps')) {
Start-FileDownload "$env:RIPPLED_DEPS_URL"
7z x rippled_deps.zip -oC:\ -y > $null
}
# TODO: This is giving me grief
# artifacts:
# # Save rippled.exe in the cloud after each build.
# - path: "build\\rippled.exe"
build_script:
# We set the environment variables needed to put compilers on the PATH.
- '"%VS120COMNTOOLS%../../VC/vcvarsall.bat" x86_amd64'
# Show which version of the compiler we are using.
- cl
- scons msvc.debug -j%NUMBER_OF_PROCESSORS%
after_build:
# Put our executable in a place where npm test can find it.
- ps: cp build/msvc.debug/rippled.exe build
- ps: ls build
test_script:
# Run the unit tests
- build\\rippled --unittest
# Run the integration tests
- npm install
- npm test

133
bin/stop-test.js Normal file
View File

@@ -0,0 +1,133 @@
/* -------------------------------- REQUIRES -------------------------------- */
var child = require("child_process");
var assert = require("assert");
/* --------------------------------- CONFIG --------------------------------- */
if (process.argv[2] == null) {
[
'Usage: ',
'',
' `node bin/stop-test.js i,j [rippled_path] [rippled_conf]`',
'',
' Launch rippled and stop it after n seconds for all n in [i, j}',
' For all even values of n launch rippled with `--fg`',
' For values of n where n % 3 == 0 launch rippled with `--fg`\n',
'Examples: ',
'',
' $ node bin/stop-test.js 5,10',
(' $ node bin/stop-test.js 1,4 ' +
'build/clang.debug/rippled $HOME/.confs/rippled.cfg')
]
.forEach(function(l){console.log(l)});
process.exit();
} else {
var testRange = process.argv[2].split(',').map(Number);
var rippledPath = process.argv[3] || 'build/rippled'
var rippledConf = process.argv[4] || 'rippled.cfg'
}
var options = {
env: process.env,
stdio: 'ignore' // we could dump the child io when it fails abnormally
};
// default args
var conf_args = ['--conf='+rippledConf];
var start_args = conf_args.concat([/*'--net'*/])
var stop_args = conf_args.concat(['stop']);
/* --------------------------------- HELPERS -------------------------------- */
function start(args) {
return child.spawn(rippledPath, args, options);
}
function stop(rippled) { child.execFile(rippledPath, stop_args, options)}
function secs_l8r(ms, f) {setTimeout(f, ms * 1000); }
function show_results_and_exit(results) {
console.log(JSON.stringify(results, undefined, 2));
process.exit();
}
var timeTakes = function (range) {
function sumRange(n) {return (n+1) * n /2}
var ret = sumRange(range[1]);
if (range[0] > 1) {
ret = ret - sumRange(range[0] - 1)
}
var stopping = (range[1] - range[0]) * 0.5;
return ret + stopping;
}
/* ---------------------------------- TEST ---------------------------------- */
console.log("Test will take ~%s seconds", timeTakes(testRange));
(function oneTest(n /* seconds */, results) {
if (n >= testRange[1]) {
// show_results_and_exit(results);
console.log(JSON.stringify(results, undefined, 2));
oneTest(testRange[0], []);
return;
}
var args = start_args;
if (n % 2 == 0) {args = args.concat(['--fg'])}
if (n % 3 == 0) {args = args.concat(['--net'])}
var result = {args: args, alive_for: n};
results.push(result);
console.log("\nLaunching `%s` with `%s` for %d seconds",
rippledPath, JSON.stringify(args), n);
rippled = start(args);
console.log("Rippled pid: %d", rippled.pid);
// defaults
var b4StopSent = false;
var stopSent = false;
var stop_took = null;
rippled.once('exit', function(){
if (!stopSent && !b4StopSent) {
console.warn('\nRippled exited itself b4 stop issued');
process.exit();
};
// The io handles close AFTER exit, may have implications for
// `stdio:'inherit'` option to `child.spawn`.
rippled.once('close', function() {
result.stop_took = (+new Date() - stop_took) / 1000; // seconds
console.log("Stopping after %d seconds took %s seconds",
n, result.stop_took);
oneTest(n+1, results);
});
});
secs_l8r(n, function(){
console.log("Stopping rippled after %d seconds", n);
// possible race here ?
// seems highly unlikely, but I was having issues at one point
b4StopSent=true;
stop_took = (+new Date());
// when does `exit` actually get sent?
stop();
stopSent=true;
// Sometimes we want to attach with a debugger.
if (process.env.ABORT_TESTS_ON_STALL != null) {
// We wait 30 seconds, and if it hasn't stopped, we abort the process
secs_l8r(30, function() {
if (result.stop_took == null) {
console.log("rippled has stalled");
process.exit();
};
});
}
})
}(testRange[0], []));

52
circle.yml Normal file
View File

@@ -0,0 +1,52 @@
machine:
services:
- docker
dependencies:
pre:
- sudo apt-add-repository -y 'deb http://llvm.org/apt/precise/ llvm-toolchain-precise-3.4 main'
- sudo apt-add-repository -y ppa:ubuntu-toolchain-r/test
- sudo add-apt-repository -y ppa:afrank/boost
- wget -q -O - http://llvm.org/apt/llvm-snapshot.gpg.key | sudo apt-key add -
- sudo apt-get update -qq
- sudo apt-get purge -qq libboost1.48-dev
- sudo apt-get install -qq libboost1.57-all-dev
- sudo apt-get install -qq clang-3.4 gcc-4.8 libobjc-4.8-dev libgcc-4.8-dev libstdc++-4.8-dev libclang1-3.4 libgcc1 libgomp1 libstdc++6 scons protobuf-compiler libprotobuf-dev libssl-dev exuberant-ctags
- sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.8 99 --slave /usr/bin/g++ g++ /usr/bin/g++-4.8
- sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-3.4 99 --slave /usr/bin/clang++ clang++ /usr/bin/clang++-3.4
- gcc --version
- clang --version
test:
pre:
- scons clang.debug
override:
- | # create gdb script
echo "set env MALLOC_CHECK_=3" > script.gdb
echo "run" >> script.gdb
echo "backtrace full" >> script.gdb
# gdb --help
- cat script.gdb | gdb --ex 'set print thread-events off' --return-child-result --args build/clang.debug/rippled --unittest
- npm install
# Use build/(gcc|clang).debug/rippled
- |
echo "exports.default_server_config = {\"rippled_path\" : \"$HOME/rippled/build/clang.debug/rippled\"};" > test/config.js
# Run integration tests
- npm test
post:
- mkdir -p build/docker/
- cp doc/rippled-example.cfg build/clang.debug/rippled build/docker/
- cp Builds/Docker/Dockerfile-testnet build/docker/Dockerfile
- mv build/docker/rippled-example.cfg build/docker/rippled.cfg
- strip build/docker/rippled
- docker build -t ripple/rippled:$CIRCLE_SHA1 build/docker/
- docker tag ripple/rippled:$CIRCLE_SHA1 ripple/rippled:latest
- docker tag ripple/rippled:$CIRCLE_SHA1 ripple/rippled:$CIRCLE_BRANCH
- docker images
deployment:
docker:
branch: /.*/
commands:
- docker login -e $DOCKER_EMAIL -u $DOCKER_USERNAME -p $DOCKER_PASSWORD
- docker push ripple/rippled:$CIRCLE_SHA1
- docker push ripple/rippled:$CIRCLE_BRANCH
- docker push ripple/rippled:latest

View File

@@ -1,19 +1,16 @@
VFALCO NOTE - This file appears to be unmaintained.
A list of rippled version numbers, and the Github pull requests they contain.
Critical protocol changes
-------------------------
Mon Apr 8 16:13:12 PDT 2013
* The JSON field "inLedger" changing to "ledger_index"
Previous
* The JSON field "metaData" changing to "meta".
* RPC ledger will no longer take "ledger", use "ledger_hash" or "ledger_index".
* "ledgerClose" events:
** "hash" DEPRECATED: use "ledger_hash"
** "seqNum" DEPRECATED: use "ledger_index"
** "closeTime" DEPRECATED: use "close" or "close_human"
* stream "rt_accounts" --> "accounts_proposed"
* stream "rt_transactions" --> "transactions_proposed"
* subscribe "username" --> "url_username"
* subscribe "password" --> "url_password"
0.28.0-b12: Includes pulls 836, 887, 902, 903 and 904.
0.28.0-b13: Includes pulls 906, 912, 913, 914 and 915.
0.28.0-b14: Includes pulls 907, 910, 922 and 923.
0.28.0-b15: Includes pulls 832, 870, 879, 883, 911, 916, 919, 920, 924, 925 and 928. FAILED pulls 909 and 926.
0.28.0-b16: Includes pulls 909, 926, 929, 931, 932, 935 and 934.
0.28.0-b17: Includes pulls 927, 939, 940, 943, 944, 945 and 949.
0.28.0-b18: Includes pulls 930, 946, 947, 948, 951, 952, 953, 954, 955, 956, 959, 960 and 962.
0.29.0-b19: Includes pulls 967, 969 and 971.
0.29.0-b20: Includes pulls 935, 942, 957, 958, 963, 964, 965, 966, 968, 972, 973, 974 and 975.
0.29.0-b21: Includes pulls 970 and 976.
0.28.1-b4: Includes pulls 968, 998, 1005, 1008, 1010, 1011 and 1012.
0.28.1-b6: Includes pulls 983, 984, 1013, 1023 and 1024.
0.28.1-b8: Includes pulls 988, 1009, 1014, 1019, 1029, 1031, 1033, 1034 and 1035.
0.28.1-b9: Includes pulls 1026, 1030, 1036, 1037, 1038, 1040, and 1041.

16
doc/Docker.md Normal file
View File

@@ -0,0 +1,16 @@
# Rippled Docker Image
Rippled has a continuous deployment pipeline that turns every git commit into a
docker image for quick testing and deployment.
To run the tip of the latest release via docker:
```$ docker run -P -v /srv/rippled/ ripple/rippled:latest```
To run the tip of active development:
```$ docker run -P -v /srv/rippled/ ripple/rippled:develop```
Where ```/srv/rippled``` points to a directory containing a rippled.cfg and
database files. By default, port 5005/tcp maps to the RPC port and 51235/udp to
the peer port.

View File

@@ -6,23 +6,21 @@
#
# Contents
#
# 1. Peer Networking
# 1. Server
#
# 2. Websocket Networking
# 2. Peer Protocol
#
# 3. RPC Networking
# 3. Ripple Protocol
#
# 4. SMS Gateway
# 4. HTTPS Client
#
# 5. Ripple Protcol
# 5. Database
#
# 6. HTTPS Client
# 6. Diagnostics
#
# 7. Database
# 7. Voting
#
# 8. Diagnostics
#
# 9. Voting
# 8. Example Settings
#
#-------------------------------------------------------------------------------
#
@@ -44,19 +42,234 @@
# or Mac style end of lines. Blank lines and lines beginning with '#' are
# ignored. Undefined sections are reserved. No escapes are currently defined.
#
# Notation
#
# In this document a simple BNF notation is used. Angle brackets denote
# required elements, square brackets denote optional elements, and single
# quotes indicate string literals. A vertical bar separating 1 or more
# elements is a logical "or"; Any one of the elements may be chosen.
# Parenthesis are notational only, and used to group elements, they are not
# part of the syntax unless they appear in quotes. White space may always
# appear between elements, it has no effect on values.
#
# <key> A required identifier
# '=' The equals sign character
# | Logical "or"
# ( ) Used for grouping
#
#
# An identifier is a string of upper or lower case letters, digits, or
# underscores subject to the requirement that the first character of an
# identifier must be a letter. Identifiers are not case sensitive (but
# values may be).
#
# Some configuration sections contain key/value pairs. A line containing
# a key/value pair has this syntax:
#
# <identifier> '=' <value>
#
# Depending on the section and key, different value types are possible:
#
# <integer> A signed integer
# <unsigned> An unsigned integer
# <flag> A boolean. 1 = true/yes/on, 0 = false/no/off.
#
# Consult the documentation on the key in question to determine the possible
# value types.
#
#
#
#-------------------------------------------------------------------------------
#
# 1. Peer Networking
# 1. Server
#
#-------------------
#----------
#
#
#
# rippled offers various server protocols to clients making inbound
# connections. The listening ports rippled uses are "universal" ports
# which may be configured to handshake in one or more of the available
# supported protocols. These universal ports simplify administration:
# A single open port can be used for multiple protocols.
#
# NOTE At least one server port must be defined in order
# to accept incoming network connections.
#
#
# [server]
#
# A list of port names and key/value pairs. A port name must start with a
# letter and contain only letters and numbers. The name is not case-sensitive.
# For each name in this list, rippled will look for a configuration file
# section with the same name and use it to create a listening port. The
# name is informational only; the choice of name does not affect the function
# of the listening port.
#
# Key/value pairs specified in this section are optional, and apply to all
# listening ports unless the port overrides the value in its section. They
# may be considered default values.
#
# Suggestion:
#
# To avoid a conflict with port names and future configuration sections,
# we recommend prepending "port_" to the port name. This prefix is not
# required, but suggested.
#
# This example defines two ports with different port numbers and settings:
#
# [server]
# port_public
# port_private
# port = 80
#
# [port_public]
# ip=0.0.0.0
# port = 443
# protocol=peer,https
#
# [port_private]
# ip=127.0.0.1
# protocol=http
#
# When rippled is used as a command line client (for example, issuing a
# server stop command), the first port advertising the http or https
# protocol will be used to make the connection.
#
#
#
# [<name>]
#
# A series of key/value pairs that define the settings for the port with
# the corresponding name. These keys are possible:
#
# ip = <IP-address>
#
# Required. Determines the IP address of the network interface to bind
# to. To bind to all available interfaces, uses 0.0.0.0
#
# port = <number>
#
# Required. Sets the port number to use for this port.
#
# protocol = [ http, https, peer ]
#
# Required. A comma-separated list of protocols to support:
#
# http JSON-RPC over HTTP
# https JSON-RPC over HTTPS
# ws Websockets
# wss Secure Websockets
# peer Peer Protocol
#
# Restrictions:
#
# Only one port may be configured to support the peer protocol.
# A port cannot have websocket and non websocket protocols at the
# same time. It is possible have both Websockets and Secure Websockets
# together in one port.
#
# NOTE If no ports support the peer protocol, rippled cannot
# receive incoming peer connections or become a superpeer.
#
# user = <text>
# password = <text>
#
# When set, these credentials will be required on HTTP/S requests.
# The credentials must be provided using HTTP's Basic Authentication
# headers. If either or both fields are empty, then no credentials are
# required. IP address restrictions, if any, will be checked in addition
# to the credentials specified here.
#
# When acting in the client role, rippled will supply these credentials
# using HTTP's Basic Authentication headers when making outbound HTTP/S
# requests.
#
# admin = [ IP, IP, IP, ... ]
#
# A comma-separated list of IP addresses.
#
# When set, grants administrative command access to the specified IP
# addresses. These commands may be issued over http, https, ws, or wss
# if configured on the port. If unspecified, the default is to not allow
# administrative commands.
#
# *SECURITY WARNING*
# 0.0.0.0 may be specified to allow access from any IP address. It must
# be the only address specified and cannot be combined with other IPs.
# Use of this address can compromise server security, please consider its
# use carefully.
#
# admin_user = <text>
# admin_password = <text>
#
# When set, clients must provide these credentials in the submitted
# JSON for any administrative command requests submitted to the HTTP/S,
# WS, or WSS protocol interfaces. If administrative commands are
# disabled for a port, these credentials have no effect.
#
# When acting in the client role, rippled will supply these credentials
# in the submitted JSON for any administrative command requests when
# invoking JSON-RPC commands on remote servers.
#
# ssl_key = <filename>
# ssl_cert = <filename>
# ssl_chain = <filename>
#
# Use the specified files when configuring SSL on the port.
#
# NOTE If no files are specified and secure protocols are selected,
# rippled will generate an internal self-signed certificate.
#
# The files have these meanings:
#
# ssl_key
#
# Specifies the filename holding the SSL key in PEM format.
#
# ssl_cert
#
# Specifies the path to the SSL certificate file in PEM format.
# This is not needed if the chain includes it.
#
# ssl_chain
#
# If you need a certificate chain, specify the path to the
# certificate chain here. The chain may include the end certificate.
#
#
#
# [rpc_startup]
#
# Specify a list of RPC commands to run at startup.
#
# Examples:
# { "command" : "server_info" }
# { "command" : "log_level", "partition" : "ripplecalc", "severity" : "trace" }
#
#
#
# [websocket_ping_frequency]
#
# <number>
#
# The amount of time to wait in seconds, before sending a websocket 'ping'
# message. Ping messages are used to determine if the remote end of the
# connection is no longer available.
#
#
#
#-------------------------------------------------------------------------------
#
# 2. Peer Protocol
#
#-----------------
#
# These settings control security and access attributes of the Peer to Peer
# server section of the rippled process. Peer Networking implements the
# server section of the rippled process. Peer Protocol implements the
# Ripple Payment protocol. It is over peer connections that transactions
# and validations are passed from to machine to machine, to make up the
# components of closed ledgers.
# and validations are passed from to machine to machine, to determine the
# contents of validated ledgers.
#
#
#
@@ -95,40 +308,6 @@
#
#
#
# [peer_ip]
#
# IP address or domain to bind to allow external connections from peers.
# Defaults to not binding, which disallows external connections from peers.
#
# Examples: 0.0.0.0 - Bind on all interfaces.
#
#
#
# [peer_port]
#
# If peer_ip is supplied, corresponding port to bind to for peer connections.
#
#
#
# [peer_port_proxy]
#
# An optional, additional listening port number for peers. Incoming
# connections on this port will be required to provide a PROXY Protocol
# handshake, described in this document (external link):
#
# http://haproxy.1wt.eu/download/1.5/doc/proxy-protocol.txt
#
# The PROXY Protocol is a popular method used by elastic load balancing
# service providers such as Amazon, to identify the true IP address and
# port number of external incoming connections.
#
# In addition to enabling this setting, it will also be required to
# use your provider-specific control panel or administrative web page
# to configure your server instance to receive PROXY Protocol handshakes,
# and also to restrict access to your instance to the Elastic Load Balancer.
#
#
#
# [peer_private]
#
# 0 or 1.
@@ -147,19 +326,6 @@
#
#
#
# [peer_ssl_cipher_list]
#
# A colon delimited string with the allowed SSL cipher modes for peer. The
# choices for for ciphers are defined by the OpenSSL API function
# SSL_CTX_set_cipher_list, documented here (external link):
#
# http://pic.dhe.ibm.com/infocenter/tpfhelp/current/index.jsp?topic=%2Fcom.ibm.ztpf-ztpfdf.doc_put.cur%2Fgtpc2%2Fcpp_ssl_ctx_set_cipher_list.html
#
# The default setting is "ALL:!LOW:!EXP:!MD5:@STRENGTH", which allows
# non-authenticated peer connections (they are, however, secure).
#
#
#
# [node_seed]
#
# This is used for clustering. To force a particular node seed or key, the
@@ -193,283 +359,45 @@
#
#
#
#-------------------------------------------------------------------------------
# [overlay] EXPERIMENTAL
#
# 2. Websocket Networking
# This section is EXPERIMENTAL, and should not be
# present for production configuration settings.
#
#------------------------
# A set of key/value pair parameters to configure the overlay.
#
# These settings control security and access attributes of the Websocket
# server section of the rippled process, primarily used to service
# client requests and backend applications.
# auto_connect = 0 | 1
#
# When set, activates the autoconnect feature. This maintains outgoing
# connections using PeerFinder's "Outgoing Connection Strategy."
#
# become_superpeer = 'never' | 'always' | 'auto'
#
# [websocket_public_ip]
# Controls the selection of peer roles:
#
# IP address or domain to bind to allow untrusted connections from clients.
# In the future, this option will go away and the peer_ip will accept
# websocket client connections.
# 'never' Always handshake in the leaf role.
# 'always' Always handshake in the superpeer role.
# 'auto' Start as a leaf, promote to superpeer after
# passing capability check (default).
#
# Examples: 0.0.0.0 - Bind on all interfaces.
# 127.0.0.1 - Bind on localhost interface. Only local programs may connect.
# In the leaf role, a peer does not advertise its IP and port for
# the purpose of receiving incoming connections. The peer also does
# not forward transactions and validations received from other peers.
#
#
#
# [websocket_public_port]
#
# Port to bind to allow untrusted connections from clients. In the future,
# this option will go away and the peer_ip will accept websocket client
# connections.
#
#
#
# [websocket_public_secure]
#
# 0, 1 or 2.
# 0: Provide ws service for websocket_public_ip/websocket_public_port.
# 1: Provide both ws and wss service for websocket_public_ip/websocket_public_port. [default]
# 2: Provide wss service only for websocket_public_ip/websocket_public_port.
#
# Browser pages like the Ripple client will not be able to connect to a secure
# websocket connection if a self-signed certificate is used. As the Ripple
# reference client currently shares secrets with its server, this should be
# enabled.
#
#
#
# [websocket_ping_frequency]
#
# <number>
#
# The amount of time to wait in seconds, before sending a websocket 'ping'
# message. Ping messages are used to determine if the remote end of the
# connection is no longer available.
#
#
#
# [websocket_ip]
#
# IP address or domain to bind to allow trusted ADMIN connections from backend
# applications.
#
# Examples: 0.0.0.0 - Bind on all interfaces.
# 127.0.0.1 - Bind on localhost interface. Only local programs may connect.
#
#
#
# [websocket_port]
#
# Port to bind to allow trusted ADMIN connections from backend applications.
#
#
#
# [websocket_secure]
#
# 0, 1, or 2.
# 0: Provide ws service only for websocket_ip/websocket_port. [default]
# 1: Provide ws and wss service for websocket_ip/websocket_port
# 2: Provide wss service for websocket_ip/websocket_port.
#
#
#
# [websocket_ssl_cert]
#
# Specify the path to the SSL certificate file in PEM format.
# This is not needed if the chain includes it.
#
#
#
# [websocket_ssl_chain]
#
# If you need a certificate chain, specify the path to the certificate chain
# here. The chain may include the end certificate.
#
#
#
# [websocket_ssl_key]
#
# Specify the filename holding the SSL key in PEM format.
# In the superpeer role, a peer advertises its IP and port for
# receiving incoming connections after passing an incoming connection
# test. Superpeers forward transactions and protocol messages to all
# other peers. Superpeers do not forward validations to other superpeers.
# Instead, a validation received by a superpeer from a leaf is forwarded
# only to other leaf connections.
#
#
#
#-------------------------------------------------------------------------------
#
# 3. RPC Networking
# 3. Ripple Protocol
#
#------------------
#
# This group of settings configures security and access attributes of the
# RPC server section of the rippled process, used to service both local
# and optional remote clients.
#
#
#
# [rpc_allow_remote]
#
# 0 or 1.
#
# 0: Allow RPC connections only from 127.0.0.1. [default]
# 1: Allow RPC connections from any IP.
#
#
#
# [rpc_admin_allow]
#
# Specify a list of IP addresses allowed to have admin access. One per line.
# If you want to test the output of non-admin commands add this section and
# just put an ip address not under your control.
# Defaults to 127.0.0.1.
#
#
#
# [rpc_admin_user]
#
# As a server, require this as the admin user to be specified. Also, require
# rpc_admin_user and rpc_admin_password to be checked for RPC admin functions.
# The request must specify these as the admin_user and admin_password in the
# request object.
#
# As a client, supply this to the server in the request object.
#
#
#
# [rpc_admin_password]
#
# As a server, require this as the admin password to be specified. Also,
# require rpc_admin_user and rpc_admin_password to be checked for RPC admin
# functions. The request must specify these as the admin_user and
# admin_password in the request object.
#
# As a client, supply this to the server in the request object.
#
#
#
# [rpc_ip]
#
# IP address or domain to bind to allow insecure RPC connections.
# Defaults to not binding, which disallows RPC connections.
#
#
#
# [rpc_port]
#
# If rpc_ip is supplied, corresponding port to bind to for peer connections.
#
#
#
# [rpc_user]
#
# As a server, require this user to be specified and require rpc_password to
# be checked for RPC access via the rpc_ip and rpc_port. The user and password
# must be specified via HTTP's basic authentication method.
# As a client, supply this to the server via HTTP's basic authentication
# method.
#
#
#
# [rpc_password]
#
# As a server, require this password to be specified and require rpc_user to
# be checked for RPC access via the rpc_ip and rpc_port. The user and password
# must be specified via HTTP's basic authentication method.
# As a client, supply this to the server via HTTP's basic authentication
# method.
#
#
#
# [rpc_startup]
#
# Specify a list of RPC commands to run at startup.
#
# Examples:
# { "command" : "server_info" }
# { "command" : "log_level", "partition" : "ripplecalc", "severity" : "trace" }
#
#
#
# [rpc_secure]
#
# 0 or 1.
#
# 0: Server certificates are not provided for RPC clients using SSL [default]
# 1: Client RPC connections wil be provided with SSL certificates.
#
# Note that if rpc_secure is enabled, it will also be necessary to configure
# the certificate file settings located in rpc_ssl_cert, rpc_ssl_chain, and
# rpc_ssl_key
#
#
#
# [rpc_ssl_cert]
#
# <pathname>
#
# A file system path leading to the SSL certificate file to use for secure
# RPC. The file is in PEM format. The file is not needed if the chain
# includes it.
#
#
#
# [rpc_ssl_chain]
#
# <pathname>
#
# A file system path leading to the file with the certificate chain.
# The chain may include the end certificate.
#
#
#
# [rpc_ssl_key]
#
# <pathname>
#
# A file system path leading to the file with the SSL key.
# The file is in PEM format.
#
#
#
#-------------------------------------------------------------------------------
#
# 4. SMS Gateway
#
#---------------
#
# If you have a certain SMS messaging provider you can configure these
# settings to allow the rippled server instance to send an SMS text to the
# configured gateway in response to an admin-level RPC command "sms" with
# one parameter, 'text' containing the message to send. This allows backend
# applications to use the rippled instance to securely notify administrators
# of custom events or information via SMS gateway.
#
# When the 'sms' RPC command is issued, the configured SMS gateway will be
# contacted via HTTPS GET at the URL indicated by sms_url. The URI formed
# will be in this format:
#
# [sms_url]?from=[sms_from]&to=[sms_to]&api_key=[sms_key]&api_secret=[sms_secret]&text=['text']
#
# Where [...] are the corresponding values from the configuration file, and
# ['test'] is the value of the JSON field with name 'text'.
#
# [sms_url]
#
# The URL to contact via HTTPS when sending SMS messages
#
# [sms_from]
# [sms_to]
# [sms_key]
# [sms_secret]
#
# These are all strings passed directly in the URI as query parameters
# to the provider of the SMS gateway.
#
#
#
#-------------------------------------------------------------------------------
#
# 5. Ripple Protocol
#
#------------------
#-------------------
#
# These settings affect the behavior of the server instance with respect
# to Ripple payment protocol level activities such as validating and
@@ -504,6 +432,8 @@
# need to serve clients can set this to "none". Servers that want complete
# history can set this to "full".
#
# This must be less than or equal to online_delete (if online_delete is used)
#
# The default is: 256
#
#
@@ -598,7 +528,7 @@
# [path_search_old]
#
# For clients that use the legacy path finding interfaces, the search
# agressivness to use. The default is 7.
# aggressiveness to use. The default is 7.
#
#
#
@@ -611,21 +541,23 @@
#
#-------------------------------------------------------------------------------
#
# 6. HTTPS Client
# 4. HTTPS Client
#
#----------------
#
# The rippled server instance uses HTTPS GET requests in a variety of
# circumstances, including but not limited to the SMS Messaging Gateway
# feature and also for contacting trusted domains to fetch information
# such as mapping an email address to a Ripple Payment Network address.
# circumstances, including but not limited to contacting trusted domains to
# fetch information such as mapping an email address to a Ripple Payment
# Network address.
#
# [ssl_verify]
#
# 0 or 1.
#
# 0. HTTPS client connections will not verify certificates.
# 1. Certificates will be checked for HTTPS client connections .
# 1. Certificates will be checked for HTTPS client connections.
#
# If not specified, this parameter defaults to 1.
#
#
#
@@ -651,7 +583,7 @@
#
#-------------------------------------------------------------------------------
#
# 7. Database
# 5. Database
#
#------------
#
@@ -684,22 +616,27 @@
# ...
#
# Examples:
# type=HyperLevelDB
# path=db/hyperldb
# compression=0
# type=rocksdb
# path=db/rocksdb
#
# Choices for 'type' (not case-sensitive)
# RocksDB Use Facebook's RocksDB database (preferred)
# HyperLevelDB Use an improved version of LevelDB
# SQLite Use SQLite
# LevelDB Use Google's LevelDB database (deprecated)
# none Use no backend
# NuDB Use Ripple Labs' NuDB (Windows preferred)
# SQLite (Deprecated)
# none (No backend)
#
# Required keys:
# path Location to store the database (all types)
#
# Optional keys:
# compression 0 for none, 1 for Snappy compression
# online_delete Minimum value of 256. Enable automatic purging
# of older ledger information. Maintain at least this
# number of ledger records online. Must be greater
# than or equal to ledger_history.
# advisory_delete 0 for disabled, 1 for enabled. If set, then
# require administrative RPC call "can_delete"
# to enable online deletion of ledger records.
#
# Notes:
# The 'node_db' entry configures the primary, persistent storage.
@@ -718,13 +655,14 @@
# There are 4 book-keeping SQLite database that the server creates and
# maintains. If you omit this configuration setting, it will default to
# creating a directory called "db" located in the same place as your
# rippled.cfg file.
# rippled.cfg file. Partial pathnames will be considered relative to
# the location of the rippled executable.
#
#
#
#-------------------------------------------------------------------------------
#
# 8. Diagnostics
# 6. Diagnostics
#
#---------------
#
@@ -745,10 +683,10 @@
#
# [insight]
#
# Configuration parameters for the Beast.Insight stats collection module.
# Configuration parameters for the Beast. Insight stats collection module.
#
# Insight is a module that collects information from the areas of rippled
# that have instrumentation. The configuration paramters control where the
# that have instrumentation. The configuration parameters control where the
# collection metrics are sent. The parameters are expressed as key = value
# pairs with no white space. The main parameter is the choice of server:
#
@@ -780,7 +718,7 @@
#
#-------------------------------------------------------------------------------
#
# 9. Voting
# 7. Voting
#
#----------
#
@@ -807,7 +745,7 @@
#
# account_reserve = <drops>
#
# The account reserve requirement specified in drops. The portion of an
# The account reserve requirement is specified in drops. The portion of an
# account's XRP balance that is at or below the reserve may only be
# spent on transaction fees, and not transferred out of the account.
#
@@ -830,41 +768,84 @@
# owner_reserve = 5000000 # 5 XRP
#
#-------------------------------------------------------------------------------
# Allow other peers to connect to this server.
#
[peer_ip]
0.0.0.0
[peer_port]
51235
# Allow untrusted clients to connect to this server.
# 8. Example Settings
#
[websocket_public_ip]
0.0.0.0
[websocket_public_port]
5006
# Provide trusted websocket ADMIN access to the localhost.
#--------------------
#
[websocket_ip]
127.0.0.1
[websocket_port]
6006
# Provide trusted json-rpc ADMIN access to the localhost.
# Administrators can use these values as a starting point for configuring
# their instance of rippled, but each value should be checked to make sure
# it meets the business requirements for the organization.
#
[rpc_ip]
127.0.0.1
# Server
#
# These example configuration settings create these ports:
#
# "peer"
#
# Peer protocol open to everyone. This is required to accept
# incoming rippled connections. This does not affect automatic
# or manual outgoing Peer protocol connections.
#
# "rpc"
#
# Administrative RPC commands over HTTPS, when originating from
# the same machine (via the loopback adapter at 127.0.0.1).
#
# "wss_admin"
#
# Admin level API commands over Secure Websockets, when originating
# from the same machine (via the loopback adapter at 127.0.0.1).
#
# This port is commented out but can be enabled by removing
# the '#' from each corresponding line including the entry under [server]
#
# "wss_public"
#
# Guest level API commands over Secure Websockets, open to everyone.
#
# For HTTPS and Secure Websockets ports, if no certificate and key file
# are specified then a self-signed certificate will be generated on startup.
# If you have a certificate and key file, uncomment the corresponding lines
# and ensure the paths to the files are correct.
#
# NOTE
#
# To accept connections on well known ports such as 80 (HTTP) or
# 443 (HTTPS), most operating systems will require rippled to
# run with administrator privileges, or else rippled will not start.
[rpc_port]
5005
[server]
port_rpc
port_peer
port_wss_admin
#port_ws_public
#ssl_key = /etc/ssl/private/server.key
#ssl_cert = /etc/ssl/certs/server.crt
[rpc_allow_remote]
0
[port_rpc]
port = 5005
ip = 127.0.0.1
admin = 127.0.0.1
protocol = https
[port_peer]
port = 51235
ip = 0.0.0.0
protocol = peer
[port_wss_admin]
port = 6006
ip = 127.0.0.1
admin = 127.0.0.1
protocol = wss
#[port_ws_public]
#port = 5005
#ip = 127.0.0.1
#protocol = wss
#-------------------------------------------------------------------------------
[node_size]
medium
@@ -872,6 +853,8 @@ medium
# This is primary persistent datastore for rippled. This includes transaction
# metadata, account states, and ledger headers. Helpful information can be
# found here: https://ripple.com/wiki/NodeBackEnd
# delete old ledgers while maintaining at least 2000. Do not require an
# external administrative command to initiate deletion.
[node_db]
type=RocksDB
path=/var/lib/rippled/db/rocksdb
@@ -880,6 +863,8 @@ filter_bits=12
cache_mb=256
file_size_mb=8
file_size_mult=2
online_delete=2000
advisory_delete=0
[database_path]
/var/lib/rippled/db
@@ -919,22 +904,7 @@ n9LdgEtkmGB9E2h3K4Vp7iGUaKuq23Zr32ehxiU8FWY7xoxbWTSA RL5
[rpc_startup]
{ "command": "log_level", "severity": "warning" }
# Configure SSL for WebSockets. Not enabled by default because not everybody
# has an SSL cert on their server, but if you uncomment the following lines and
# set the path to the SSL certificate and private key the WebSockets protocol
# will be protected by SSL/TLS.
#[websocket_secure]
#1
#[websocket_ssl_cert]
#/etc/ssl/certs/server.crt
#[websocket_ssl_key]
#/etc/ssl/private/server.key
# Defaults to 0 ("no") so that you can use self-signed SSL certificates for
# development, or internally.
# Defaults to 1 ("yes") so that certificates will be validated. To allow the use
# of self-signed certificates for development or internal use, set to 0 ("no").
#[ssl_verify]
#0

BIN
images/build.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
images/contribute.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
images/network.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

BIN
images/pathfinding.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

BIN
images/ripple.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

BIN
images/transact.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
images/vehicle_currency.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

View File

@@ -2,33 +2,30 @@
"name": "rippled",
"version": "0.0.1",
"description": "Rippled Server",
"private": true,
"directories": {
"test": "test"
},
"dependencies": {
"ripple-lib": "0.8.2",
"async": "~0.2.9",
"deep-equal": "0.0.0",
"extend": "~1.2.0",
"simple-jsonrpc": "~0.0.2",
"deep-equal": "0.0.0"
"lodash": "^3.5.0",
"request": "^2.47.0",
"ripple-lib": "0.10.0",
"simple-jsonrpc": "~0.0.2"
},
"devDependencies": {
"coffee-script": "~1.6.3",
"mocha": "~1.13.0"
"assert-diff": "^1.0.1",
"coffee-script": "^1.8.0",
"mocha": "^2.1.0"
},
"scripts": {
"test": "mocha test/websocket-test.js test/server-test.js test/*-test.{js,coffee}"
},
"repository": {
"type": "git",
"url": "git://github.com/ripple/rippled.git"
},
"readmeFilename": "README.md"
}

View File

@@ -59,24 +59,11 @@
/** Config: BEAST_CHECK_MEMORY_LEAKS
Enables a memory-leak check for certain objects when the app terminates.
See the LeakChecked class for more details about enabling leak checking for
specific classes.
*/
#ifndef BEAST_CHECK_MEMORY_LEAKS
//#define BEAST_CHECK_MEMORY_LEAKS 0
#endif
/** Config: BEAST_COMPILER_CHECKS_SOCKET_OVERRIDES
Setting this option makes Socket-derived classes generate compile errors
if they forget any of the virtual overrides As some Socket-derived classes
intentionally omit member functions that are not applicable, this macro
should only be enabled temporarily when writing your own Socket-derived
class, to make sure that the function signatures match as expected.
*/
#ifndef BEAST_COMPILER_CHECKS_SOCKET_OVERRIDES
//#define BEAST_COMPILER_CHECKS_SOCKET_OVERRIDES 1
#endif
//------------------------------------------------------------------------------
//
// Libraries
@@ -193,13 +180,6 @@
#define RIPPLE_PROPOSE_AMENDMENTS 0
#endif
/** Config: RIPPLE_ENABLE_AUTOBRIDGING
This determines whether ripple implements offer autobridging via XRP.
*/
#ifndef RIPPLE_ENABLE_AUTOBRIDGING
#define RIPPLE_ENABLE_AUTOBRIDGING 0
#endif
/** Config: RIPPLE_SINGLE_IO_SERVICE_THREAD
When set, restricts the number of threads calling io_service::run to one.
This is useful when debugging.
@@ -208,17 +188,18 @@
#define RIPPLE_SINGLE_IO_SERVICE_THREAD 0
#endif
/** Config: RIPPLE_STRUCTURED_OVERLAY_CLIENT
RIPPLE_STRUCTURED_OVERLAY_SERVER
Enables Structured Overlay support for the client or server roles.
This feature is currently in development:
https://ripplelabs.atlassian.net/browse/RIPD-157
/** Config: RIPPLE_HOOK_VALIDATORS
Activates code for handling validations and validators (work in progress).
*/
#ifndef RIPPLE_STRUCTURED_OVERLAY_CLIENT
#define RIPPLE_STRUCTURED_OVERLAY_CLIENT 0
#ifndef RIPPLE_HOOK_VALIDATORS
#define RIPPLE_HOOK_VALIDATORS 0
#endif
#ifndef RIPPLE_STRUCTURED_OVERLAY_SERVER
#define RIPPLE_STRUCTURED_OVERLAY_SERVER 1
/** Config: RIPPLE_ENABLE_TICKETS
Enables processing of ticket transactions
*/
#ifndef RIPPLE_ENABLE_TICKETS
#define RIPPLE_ENABLE_TICKETS 0
#endif
#endif

View File

@@ -64,17 +64,6 @@
//#define BEAST_CHECK_MEMORY_LEAKS 0
#endif
/** Config: BEAST_COMPILER_CHECKS_SOCKET_OVERRIDES
Setting this option makes Socket-derived classes generate compile errors
if they forget any of the virtual overrides As some Socket-derived classes
intentionally omit member functions that are not applicable, this macro
should only be enabled temporarily when writing your own Socket-derived
class, to make sure that the function signatures match as expected.
*/
#ifndef BEAST_COMPILER_CHECKS_SOCKET_OVERRIDES
//#define BEAST_COMPILER_CHECKS_SOCKET_OVERRIDES 1
#endif
//------------------------------------------------------------------------------
//
// Libraries

View File

@@ -1,429 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Portions of this file are from JUCE.
Copyright (c) 2013 - Raw Material Software Ltd.
Please visit http://www.juce.com
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 BEAST_ATOMIC_H_INCLUDED
#define BEAST_ATOMIC_H_INCLUDED
#include <beast/Config.h>
#include <beast/utility/noexcept.h>
#include <cstdint>
namespace beast {
//==============================================================================
/**
Simple class to hold a primitive value and perform atomic operations on it.
The type used must be a 32 or 64 bit primitive, like an int, pointer, etc.
There are methods to perform most of the basic atomic operations.
*/
template <typename Type>
class Atomic
{
// This class can only be used for types which are 32 or 64 bits in size.
static_assert (sizeof (Type) == 4 || sizeof (Type) == 8,
"Atomic arguments must be 32- or 64-bit long primitive types.");
public:
/** Creates a new value, initialised to zero. */
inline Atomic() noexcept
: value (0)
{
}
/** Creates a new value, with a given initial value. */
inline Atomic (const Type initialValue) noexcept
: value (initialValue)
{
}
/** Copies another value (atomically). */
inline Atomic (const Atomic& other) noexcept
: value (other.get())
{
}
/** Destructor. */
inline ~Atomic() noexcept
{
}
/** Atomically reads and returns the current value. */
Type get() const noexcept;
/** Copies another value onto this one (atomically). */
Atomic& operator= (const Atomic& other) noexcept
{ exchange (other.get()); return *this; }
/** Copies another value onto this one (atomically). */
Atomic& operator= (const Type newValue) noexcept
{ exchange (newValue); return *this; }
/** Atomically sets the current value. */
void set (Type newValue) noexcept
{ exchange (newValue); }
/** Atomically sets the current value, returning the value that was replaced. */
Type exchange (Type value) noexcept;
/** Atomically adds a number to this value, returning the new value. */
Type operator+= (Type amountToAdd) noexcept;
/** Atomically subtracts a number from this value, returning the new value. */
Type operator-= (Type amountToSubtract) noexcept;
/** Atomically increments this value, returning the new value. */
Type operator++() noexcept;
/** Atomically decrements this value, returning the new value. */
Type operator--() noexcept;
/** Atomically compares this value with a target value, and if it is equal, sets
this to be equal to a new value.
This operation is the atomic equivalent of doing this:
@code
bool compareAndSetBool (Type newValue, Type valueToCompare)
{
if (get() == valueToCompare)
{
set (newValue);
return true;
}
return false;
}
@endcode
@returns true if the comparison was true and the value was replaced; false if
the comparison failed and the value was left unchanged.
@see compareAndSetValue
*/
bool compareAndSetBool (Type newValue, Type valueToCompare) noexcept;
/** Atomically compares this value with a target value, and if it is equal, sets
this to be equal to a new value.
This operation is the atomic equivalent of doing this:
@code
Type compareAndSetValue (Type newValue, Type valueToCompare)
{
Type oldValue = get();
if (oldValue == valueToCompare)
set (newValue);
return oldValue;
}
@endcode
@returns the old value before it was changed.
@see compareAndSetBool
*/
Type compareAndSetValue (Type newValue, Type valueToCompare) noexcept;
//==============================================================================
#if BEAST_64BIT
BEAST_ALIGN (8)
#else
BEAST_ALIGN (4)
#endif
/** The raw value that this class operates on.
This is exposed publically in case you need to manipulate it directly
for performance reasons.
*/
volatile Type value;
private:
template <typename Dest, typename Source>
static inline Dest castTo (Source value) noexcept { union { Dest d; Source s; } u; u.s = value; return u.d; }
static inline Type castFrom32Bit (std::int32_t value) noexcept { return castTo <Type, std::int32_t> (value); }
static inline Type castFrom64Bit (std::int64_t value) noexcept { return castTo <Type, std::int64_t> (value); }
static inline std::int32_t castTo32Bit (Type value) noexcept { return castTo <std::int32_t, Type> (value); }
static inline std::int64_t castTo64Bit (Type value) noexcept { return castTo <std::int64_t, Type> (value); }
Type operator++ (int); // better to just use pre-increment with atomics..
Type operator-- (int);
/** This templated negate function will negate pointers as well as integers */
template <typename ValueType>
inline ValueType negateValue (ValueType n) noexcept
{
return sizeof (ValueType) == 1 ? (ValueType) -(signed char) n
: (sizeof (ValueType) == 2 ? (ValueType) -(short) n
: (sizeof (ValueType) == 4 ? (ValueType) -(int) n
: ((ValueType) -(std::int64_t) n)));
}
/** This templated negate function will negate pointers as well as integers */
template <typename PointerType>
inline PointerType* negateValue (PointerType* n) noexcept
{
return reinterpret_cast <PointerType*> (-reinterpret_cast <std::intptr_t> (n));
}
};
//==============================================================================
/*
The following code is in the header so that the atomics can be inlined where possible...
*/
#if BEAST_IOS || (BEAST_MAC && (BEAST_PPC || BEAST_CLANG || __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 2)))
#define BEAST_ATOMICS_MAC 1 // Older OSX builds using gcc4.1 or earlier
#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
#define BEAST_MAC_ATOMICS_VOLATILE
#else
#define BEAST_MAC_ATOMICS_VOLATILE volatile
#endif
#if BEAST_PPC || BEAST_IOS
// None of these atomics are available for PPC or for iOS 3.1 or earlier!!
template <typename Type> static Type OSAtomicAdd64Barrier (Type b, BEAST_MAC_ATOMICS_VOLATILE Type* a) noexcept { bassertfalse; return *a += b; }
template <typename Type> static Type OSAtomicIncrement64Barrier (BEAST_MAC_ATOMICS_VOLATILE Type* a) noexcept { bassertfalse; return ++*a; }
template <typename Type> static Type OSAtomicDecrement64Barrier (BEAST_MAC_ATOMICS_VOLATILE Type* a) noexcept { bassertfalse; return --*a; }
template <typename Type> static bool OSAtomicCompareAndSwap64Barrier (Type old, Type newValue, BEAST_MAC_ATOMICS_VOLATILE Type* value) noexcept
{ bassertfalse; if (old == *value) { *value = newValue; return true; } return false; }
#define BEAST_64BIT_ATOMICS_UNAVAILABLE 1
#endif
#elif BEAST_CLANG && BEAST_LINUX
#define BEAST_ATOMICS_GCC 1
//==============================================================================
#elif BEAST_GCC
#define BEAST_ATOMICS_GCC 1 // GCC with intrinsics
#if BEAST_IOS || BEAST_ANDROID // (64-bit ops will compile but not link on these mobile OSes)
#define BEAST_64BIT_ATOMICS_UNAVAILABLE 1
#endif
//==============================================================================
#else
#define BEAST_ATOMICS_WINDOWS 1 // Windows with intrinsics
#if BEAST_USE_INTRINSICS
#ifndef __INTEL_COMPILER
#pragma intrinsic (_InterlockedExchange, _InterlockedIncrement, _InterlockedDecrement, _InterlockedCompareExchange, \
_InterlockedCompareExchange64, _InterlockedExchangeAdd, _ReadWriteBarrier)
#endif
#define beast_InterlockedExchange(a, b) _InterlockedExchange(a, b)
#define beast_InterlockedIncrement(a) _InterlockedIncrement(a)
#define beast_InterlockedDecrement(a) _InterlockedDecrement(a)
#define beast_InterlockedExchangeAdd(a, b) _InterlockedExchangeAdd(a, b)
#define beast_InterlockedCompareExchange(a, b, c) _InterlockedCompareExchange(a, b, c)
#define beast_InterlockedCompareExchange64(a, b, c) _InterlockedCompareExchange64(a, b, c)
#define beast_MemoryBarrier _ReadWriteBarrier
#else
long beast_InterlockedExchange (volatile long* a, long b) noexcept;
long beast_InterlockedIncrement (volatile long* a) noexcept;
long beast_InterlockedDecrement (volatile long* a) noexcept;
long beast_InterlockedExchangeAdd (volatile long* a, long b) noexcept;
long beast_InterlockedCompareExchange (volatile long* a, long b, long c) noexcept;
__int64 beast_InterlockedCompareExchange64 (volatile __int64* a, __int64 b, __int64 c) noexcept;
inline void beast_MemoryBarrier() noexcept { long x = 0; beast_InterlockedIncrement (&x); }
#endif
#if BEAST_64BIT
#ifndef __INTEL_COMPILER
#pragma intrinsic (_InterlockedExchangeAdd64, _InterlockedExchange64, _InterlockedIncrement64, _InterlockedDecrement64)
#endif
#define beast_InterlockedExchangeAdd64(a, b) _InterlockedExchangeAdd64(a, b)
#define beast_InterlockedExchange64(a, b) _InterlockedExchange64(a, b)
#define beast_InterlockedIncrement64(a) _InterlockedIncrement64(a)
#define beast_InterlockedDecrement64(a) _InterlockedDecrement64(a)
#else
// None of these atomics are available in a 32-bit Windows build!!
template <typename Type> static Type beast_InterlockedExchangeAdd64 (volatile Type* a, Type b) noexcept { bassertfalse; Type old = *a; *a += b; return old; }
template <typename Type> static Type beast_InterlockedExchange64 (volatile Type* a, Type b) noexcept { bassertfalse; Type old = *a; *a = b; return old; }
template <typename Type> static Type beast_InterlockedIncrement64 (volatile Type* a) noexcept { bassertfalse; return ++*a; }
template <typename Type> static Type beast_InterlockedDecrement64 (volatile Type* a) noexcept { bassertfalse; return --*a; }
#define BEAST_64BIT_ATOMICS_UNAVAILABLE 1
#endif
#endif
#if BEAST_MSVC
#pragma warning (push)
#pragma warning (disable: 4311) // (truncation warning)
#endif
//==============================================================================
template <typename Type>
inline Type Atomic<Type>::get() const noexcept
{
#if BEAST_ATOMICS_MAC
return sizeof (Type) == 4 ? castFrom32Bit ((std::int32_t) OSAtomicAdd32Barrier ((int32_t) 0, (BEAST_MAC_ATOMICS_VOLATILE int32_t*) &value))
: castFrom64Bit ((std::int64_t) OSAtomicAdd64Barrier ((int64_t) 0, (BEAST_MAC_ATOMICS_VOLATILE int64_t*) &value));
#elif BEAST_ATOMICS_WINDOWS
return sizeof (Type) == 4 ? castFrom32Bit ((std::int32_t) beast_InterlockedExchangeAdd ((volatile long*) &value, (long) 0))
: castFrom64Bit ((std::int64_t) beast_InterlockedExchangeAdd64 ((volatile __int64*) &value, (__int64) 0));
#elif BEAST_ATOMICS_GCC
return sizeof (Type) == 4 ? castFrom32Bit ((std::int32_t) __sync_add_and_fetch ((volatile std::int32_t*) &value, 0))
: castFrom64Bit ((std::int64_t) __sync_add_and_fetch ((volatile std::int64_t*) &value, 0));
#endif
}
template <typename Type>
inline Type Atomic<Type>::exchange (const Type newValue) noexcept
{
#if BEAST_ATOMICS_MAC || BEAST_ATOMICS_GCC
Type currentVal = value;
while (! compareAndSetBool (newValue, currentVal)) { currentVal = value; }
return currentVal;
#elif BEAST_ATOMICS_WINDOWS
return sizeof (Type) == 4 ? castFrom32Bit ((std::int32_t) beast_InterlockedExchange ((volatile long*) &value, (long) castTo32Bit (newValue)))
: castFrom64Bit ((std::int64_t) beast_InterlockedExchange64 ((volatile __int64*) &value, (__int64) castTo64Bit (newValue)));
#endif
}
template <typename Type>
inline Type Atomic<Type>::operator+= (const Type amountToAdd) noexcept
{
#if BEAST_ATOMICS_MAC
# ifdef __clang__
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wint-to-void-pointer-cast"
# pragma clang diagnostic ignored "-Wint-to-pointer-cast"
# endif
return sizeof (Type) == 4 ? (Type) OSAtomicAdd32Barrier ((int32_t) castTo32Bit (amountToAdd), (BEAST_MAC_ATOMICS_VOLATILE int32_t*) &value)
: (Type) OSAtomicAdd64Barrier ((int64_t) amountToAdd, (BEAST_MAC_ATOMICS_VOLATILE int64_t*) &value);
# ifdef __clang__
# pragma clang diagnostic pop
# endif
#elif BEAST_ATOMICS_WINDOWS
return sizeof (Type) == 4 ? (Type) (beast_InterlockedExchangeAdd ((volatile long*) &value, (long) amountToAdd) + (long) amountToAdd)
: (Type) (beast_InterlockedExchangeAdd64 ((volatile __int64*) &value, (__int64) amountToAdd) + (__int64) amountToAdd);
#elif BEAST_ATOMICS_GCC
return (Type) __sync_add_and_fetch (&value, amountToAdd);
#endif
}
template <typename Type>
inline Type Atomic<Type>::operator-= (const Type amountToSubtract) noexcept
{
return operator+= (negateValue (amountToSubtract));
}
template <typename Type>
inline Type Atomic<Type>::operator++() noexcept
{
#if BEAST_ATOMICS_MAC
# ifdef __clang__
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wint-to-void-pointer-cast"
# pragma clang diagnostic ignored "-Wint-to-pointer-cast"
# endif
return sizeof (Type) == 4 ? (Type) OSAtomicIncrement32Barrier ((BEAST_MAC_ATOMICS_VOLATILE int32_t*) &value)
: (Type) OSAtomicIncrement64Barrier ((BEAST_MAC_ATOMICS_VOLATILE int64_t*) &value);
# ifdef __clang__
# pragma clang diagnostic pop
# endif
#elif BEAST_ATOMICS_WINDOWS
return sizeof (Type) == 4 ? (Type) beast_InterlockedIncrement ((volatile long*) &value)
: (Type) beast_InterlockedIncrement64 ((volatile __int64*) &value);
#elif BEAST_ATOMICS_GCC
return (Type) __sync_add_and_fetch (&value, (Type) 1);
#endif
}
template <typename Type>
inline Type Atomic<Type>::operator--() noexcept
{
#if BEAST_ATOMICS_MAC
# ifdef __clang__
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wint-to-void-pointer-cast"
# pragma clang diagnostic ignored "-Wint-to-pointer-cast"
# endif
return sizeof (Type) == 4 ? (Type) OSAtomicDecrement32Barrier ((BEAST_MAC_ATOMICS_VOLATILE int32_t*) &value)
: (Type) OSAtomicDecrement64Barrier ((BEAST_MAC_ATOMICS_VOLATILE int64_t*) &value);
# ifdef __clang__
# pragma clang diagnostic pop
# endif
#elif BEAST_ATOMICS_WINDOWS
return sizeof (Type) == 4 ? (Type) beast_InterlockedDecrement ((volatile long*) &value)
: (Type) beast_InterlockedDecrement64 ((volatile __int64*) &value);
#elif BEAST_ATOMICS_GCC
return (Type) __sync_add_and_fetch (&value, (Type) -1);
#endif
}
template <typename Type>
inline bool Atomic<Type>::compareAndSetBool (const Type newValue, const Type valueToCompare) noexcept
{
#if BEAST_ATOMICS_MAC
return sizeof (Type) == 4 ? OSAtomicCompareAndSwap32Barrier ((int32_t) castTo32Bit (valueToCompare), (int32_t) castTo32Bit (newValue), (BEAST_MAC_ATOMICS_VOLATILE int32_t*) &value)
: OSAtomicCompareAndSwap64Barrier ((int64_t) castTo64Bit (valueToCompare), (int64_t) castTo64Bit (newValue), (BEAST_MAC_ATOMICS_VOLATILE int64_t*) &value);
#elif BEAST_ATOMICS_WINDOWS
return compareAndSetValue (newValue, valueToCompare) == valueToCompare;
#elif BEAST_ATOMICS_GCC
return sizeof (Type) == 4 ? __sync_bool_compare_and_swap ((volatile std::int32_t*) &value, castTo32Bit (valueToCompare), castTo32Bit (newValue))
: __sync_bool_compare_and_swap ((volatile std::int64_t*) &value, castTo64Bit (valueToCompare), castTo64Bit (newValue));
#endif
}
template <typename Type>
inline Type Atomic<Type>::compareAndSetValue (const Type newValue, const Type valueToCompare) noexcept
{
#if BEAST_ATOMICS_MAC
for (;;) // Annoying workaround for only having a bool CAS operation..
{
if (compareAndSetBool (newValue, valueToCompare))
return valueToCompare;
const Type result = value;
if (result != valueToCompare)
return result;
}
#elif BEAST_ATOMICS_WINDOWS
return sizeof (Type) == 4 ? castFrom32Bit ((std::int32_t) beast_InterlockedCompareExchange ((volatile long*) &value, (long) castTo32Bit (newValue), (long) castTo32Bit (valueToCompare)))
: castFrom64Bit ((std::int64_t) beast_InterlockedCompareExchange64 ((volatile __int64*) &value, (__int64) castTo64Bit (newValue), (__int64) castTo64Bit (valueToCompare)));
#elif BEAST_ATOMICS_GCC
return sizeof (Type) == 4 ? castFrom32Bit ((std::int32_t) __sync_val_compare_and_swap ((volatile std::int32_t*) &value, castTo32Bit (valueToCompare), castTo32Bit (newValue)))
: castFrom64Bit ((std::int64_t) __sync_val_compare_and_swap ((volatile std::int64_t*) &value, castTo64Bit (valueToCompare), castTo64Bit (newValue)));
#endif
}
inline void memoryBarrier() noexcept
{
#if BEAST_ATOMICS_MAC
OSMemoryBarrier();
#elif BEAST_ATOMICS_GCC
__sync_synchronize();
#elif BEAST_ATOMICS_WINDOWS
beast_MemoryBarrier();
#endif
}
#if BEAST_MSVC
#pragma warning (pop)
#endif
}
#endif

View File

@@ -26,9 +26,6 @@
// VFALCO NOTE this is analogous to <boost/config.hpp>
// Assert to boost that we always have std::array support
#define BOOST_ASIO_HAS_STD_ARRAY 1
#if !defined(BEAST_COMPILER_CONFIG) && !defined(BEAST_NO_COMPILER_CONFIG) && !defined(BEAST_NO_CONFIG)
#include <beast/config/SelectCompilerConfig.h>
#endif

View File

@@ -20,7 +20,6 @@
#ifndef BEAST_CRYPTO_H_INCLUDED
#define BEAST_CRYPTO_H_INCLUDED
#include <beast/crypto/MurmurHash.h>
#include <beast/crypto/Sha256.h>
#endif

View File

@@ -25,11 +25,9 @@
#include <beast/threads/SharedLockGuard.h>
#include <beast/threads/SharedMutexAdapter.h>
#include <beast/threads/SharedData.h>
#include <beast/threads/ServiceQueue.h>
#include <beast/threads/SpinLock.h>
#include <beast/threads/Stoppable.h>
#include <beast/threads/Thread.h>
#include <beast/threads/ThreadLocalValue.h>
#include <beast/threads/WaitableEvent.h>
#include <beast/threads/ScopedWrapperContext.h>

View File

@@ -22,5 +22,8 @@
#endif
#include <beast/asio/impl/IPAddressConversion.cpp>
#include <beast/asio/impl/error.cpp>
#include <beast/asio/tests/bind_handler.test.cpp>
#include <beast/asio/tests/streambuf.test.cpp>
#include <beast/asio/tests/error_test.cpp>

View File

@@ -17,11 +17,11 @@
*/
//==============================================================================
#ifndef BEAST_ASIO_SSL_H_INCLUDED
#define BEAST_ASIO_SSL_H_INCLUDED
#ifndef BEAST_ASIO_ERROR_H_INCLUDED
#define BEAST_ASIO_ERROR_H_INCLUDED
#include <boost/asio.hpp>
#include <boost/asio/ssl/error.hpp>
#include <boost/system/error_code.hpp>
namespace beast {
namespace asio {
@@ -32,8 +32,12 @@ bool
is_short_read (boost::system::error_code const& ec)
{
return (ec.category() == boost::asio::error::get_ssl_category())
&& (ERR_GET_REASON(ec.value()) == SSL_R_SHORT_READ);
&& (ERR_GET_REASON(ec.value()) == SSL_R_SHORT_READ);
}
/** Returns a human readable message if the error code is SSL related. */
std::string
asio_message(boost::system::error_code const& ec);
}
}

View File

@@ -0,0 +1,59 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
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.
*/
//==============================================================================
#include <beast/asio/error.h>
#include <boost/lexical_cast.hpp>
namespace beast {
namespace asio {
// This buffer must be at least 120 bytes, most examples use 256.
// https://www.openssl.org/docs/crypto/ERR_error_string.html
static std::uint32_t const errorBufferSize (256);
std::string
asio_message (boost::system::error_code const& ec)
{
std::string error;
if (ec.category () == boost::asio::error::get_ssl_category ())
{
error = " ("
+ boost::lexical_cast<std::string> (ERR_GET_LIB (ec.value ()))
+ ","
+ boost::lexical_cast<std::string> (ERR_GET_FUNC (ec.value ()))
+ ","
+ boost::lexical_cast<std::string> (ERR_GET_REASON (ec.value ()))
+ ") ";
//
char buf[errorBufferSize];
::ERR_error_string_n (ec.value (), buf, errorBufferSize);
error += buf;
}
else
{
error = ec.message ();
}
return error;
}
}
}

View File

@@ -21,7 +21,9 @@
#define BEAST_ASIO_SSL_BUNDLE_H_INCLUDED
#include <boost/asio/ip/tcp.hpp>
#include <boost/asio/ssl/context.hpp>
#include <boost/asio/ssl/stream.hpp>
#include <memory>
#include <utility>
namespace beast {
@@ -33,21 +35,33 @@ namespace asio {
*/
struct ssl_bundle
{
typedef boost::asio::ip::tcp::socket socket_type;
typedef boost::asio::ssl::stream <socket_type&> stream_type;
using socket_type = boost::asio::ip::tcp::socket;
using stream_type = boost::asio::ssl::stream <socket_type&>;
using shared_context = std::shared_ptr<boost::asio::ssl::context>;
template <class... Args>
ssl_bundle (boost::asio::ssl::context& context, Args&&... args);
ssl_bundle (shared_context const& context_, Args&&... args);
// DEPRECATED
template <class... Args>
ssl_bundle (boost::asio::ssl::context& context_, Args&&... args);
shared_context context;
socket_type socket;
stream_type stream;
};
template <class... Args>
ssl_bundle::ssl_bundle (boost::asio::ssl::context& context,
Args&&... args)
ssl_bundle::ssl_bundle (shared_context const& context_, Args&&... args)
: socket(std::forward<Args>(args)...)
, stream (socket, context)
, stream (socket, *context_)
{
}
template <class... Args>
ssl_bundle::ssl_bundle (boost::asio::ssl::context& context_, Args&&... args)
: socket(std::forward<Args>(args)...)
, stream (socket, context_)
{
}

View File

@@ -0,0 +1,679 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
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 BEAST_ASIO_STREAMBUF_H_INCLUDED
#define BEAST_ASIO_STREAMBUF_H_INCLUDED
#include <beast/utility/empty_base_optimization.h>
#include <boost/asio/buffer.hpp>
#include <boost/intrusive/list.hpp>
#include <boost/iterator/transform_iterator.hpp>
#include <algorithm>
#include <cassert>
#include <memory>
#include <exception>
#include <beast/cxx14/type_traits.h> // <type_traits>
#include <string>
#include <utility>
namespace beast {
namespace asio {
/** Implements asio::streambuf interface using multiple buffers. */
template <class Allocator>
class basic_streambuf
: private empty_base_optimization<Allocator>
{
public:
using size_type = typename std::allocator_traits<Allocator>::size_type;
using const_buffer = boost::asio::const_buffer;
using mutable_buffer = boost::asio::mutable_buffer;
private:
class element;
using alloc_traits = std::allocator_traits<Allocator>;
using list_type = typename boost::intrusive::make_list <element,
boost::intrusive::constant_time_size <true>>::type;
using iterator = typename list_type::iterator;
using const_iterator = typename list_type::const_iterator;
/* These diagrams illustrate the layout and state variables.
Input and output contained entirely in one element:
0 out_
|<-------------+------------------------------------------->|
in_pos_ out_pos_ out_end_
Output contained in first and second elements:
out_
|<------+----------+------->| |<----------+-------------->|
in_pos_ out_pos_ out_end_
Output contained in the second element:
out_
|<------------+------------>| |<----+-------------------->|
in_pos_ out_pos_ out_end_
Output contained in second and third elements:
out_
|<-----+-------->| |<-------+------>| |<--------------->|
in_pos_ out_pos_ out_end_
Input sequence is empty:
out_
|<------+------------------>| |<-----------+------------->|
out_pos_ out_end_
in_pos_
Output sequence is empty:
out_
|<------+------------------>| |<------+------------------>|
in_pos_ out_pos_
out_end_
The end of output can point to the end of an element.
But out_pos_ should never point to the end:
out_
|<------+------------------>| |<------+------------------>|
in_pos_ out_pos_ out_end_
When the input sequence entirely fills the last element and
the output sequence is empty, out_ will point to the end of
the list of buffers, and out_pos_ and out_end_ will be 0:
|<------+------------------>| out_ == list_.end()
in_pos_ out_pos_ == 0
out_end_ == 0
*/
list_type list_;
size_type block_size_;
size_type block_size_next_;
size_type in_size_ = 0; // size of the input sequence
iterator out_; // element that contains out_pos_
size_type in_pos_ = 0; // input offset in list_.front()
size_type out_pos_ = 0; // output offset in *out_
size_type out_end_ = 0; // output end offset in list_.back()
public:
class const_buffers_type;
class mutable_buffers_type;
basic_streambuf (basic_streambuf const& other) = delete;
basic_streambuf& operator= (basic_streambuf const& other) = delete;
basic_streambuf& operator= (basic_streambuf&& other) = delete;
~basic_streambuf();
explicit
basic_streambuf(std::size_t block_size = 16*1024,
Allocator const& alloc = Allocator{});
basic_streambuf (basic_streambuf&& other);
/** Get the maximum size of the basic_streambuf. */
size_type
max_size() const
{
return std::numeric_limits<std::size_t>::max();
}
/** Get the size of the input sequence. */
size_type
size() const
{
return in_size_;
}
/** Get a list of buffers that represents the output sequence, with the given size. */
mutable_buffers_type
prepare (size_type n);
/** Move bytes from the output sequence to the input sequence. */
void
commit (size_type n);
/** Get a list of buffers that represents the input sequence. */
const_buffers_type
data() const;
/** Remove bytes from the input sequence. */
void
consume (size_type n);
private:
void
debug_check() const;
};
//------------------------------------------------------------------------------
template <class Allocator>
class basic_streambuf<Allocator>::element
: public boost::intrusive::list_base_hook <
boost::intrusive::link_mode <boost::intrusive::normal_link>>
{
private:
size_type const size_; // size of the allocation minus sizeof(element)
public:
element (element const&) = delete;
element& operator= (element const&) = delete;
explicit
element (size_type block_size)
: size_(block_size)
{ }
size_type
size() const
{
return size_;
}
size_type
alloc_size() const
{
return size_ + sizeof(*this);
}
char*
data() const
{
return const_cast<char*>(
reinterpret_cast<char const*>(this+1));
}
};
//------------------------------------------------------------------------------
template <class Allocator>
class basic_streambuf<Allocator>::const_buffers_type
{
public:
using value_type = const_buffer;
private:
struct transform
{
using argument_type = element;
using result_type = value_type;
basic_streambuf const* streambuf_ = nullptr;
transform() = default;
explicit
transform (basic_streambuf const& streambuf)
: streambuf_ (&streambuf)
{
}
value_type const
operator() (element const& e) const;
};
basic_streambuf const* streambuf_ = nullptr;
public:
using const_iterator = boost::transform_iterator<
transform, typename list_type::const_iterator,
value_type, value_type>;
const_buffers_type() = default;
const_buffers_type (const_buffers_type const&) = default;
const_buffers_type& operator= (const_buffers_type const&) = default;
const_iterator
begin() const
{
return const_iterator (streambuf_->list_.begin(),
transform(*streambuf_));
}
const_iterator
end() const
{
return const_iterator (streambuf_->out_ ==
streambuf_->list_.end() ? streambuf_->list_.end() :
std::next(streambuf_->out_), transform(*streambuf_));
}
private:
friend class basic_streambuf;
explicit
const_buffers_type (basic_streambuf const& streambuf);
};
template <class Allocator>
basic_streambuf<Allocator>::const_buffers_type::const_buffers_type (
basic_streambuf const& streambuf)
: streambuf_ (&streambuf)
{
}
template <class Allocator>
auto
basic_streambuf<Allocator>::const_buffers_type::
transform::operator() (element const& e) const ->
value_type const
{
return value_type (e.data(),
(streambuf_->out_ == streambuf_->list_.end() ||
&e != &*streambuf_->out_) ? e.size() : streambuf_->out_pos_) +
(&e == &*streambuf_->list_.begin() ?
streambuf_->in_pos_ : 0);
}
//------------------------------------------------------------------------------
template <class Allocator>
class basic_streambuf<Allocator>::mutable_buffers_type
{
public:
using value_type = mutable_buffer;
private:
struct transform
{
using argument_type = element;
using result_type = value_type;
basic_streambuf const* streambuf_ = nullptr;
transform() = default;
explicit
transform (basic_streambuf const& streambuf)
: streambuf_ (&streambuf)
{
}
value_type const
operator() (element const& e) const;
};
basic_streambuf const* streambuf_;
public:
using const_iterator = boost::transform_iterator<
transform, typename list_type::const_iterator,
value_type, value_type>;
mutable_buffers_type() = default;
mutable_buffers_type (mutable_buffers_type const&) = default;
mutable_buffers_type& operator= (mutable_buffers_type const&) = default;
const_iterator
begin() const
{
return const_iterator (streambuf_->out_,
transform(*streambuf_));
}
const_iterator
end() const
{
return const_iterator (streambuf_->list_.end(),
transform(*streambuf_));
}
private:
friend class basic_streambuf;
mutable_buffers_type (basic_streambuf const& streambuf);
};
template <class Allocator>
basic_streambuf<Allocator>::mutable_buffers_type::mutable_buffers_type (
basic_streambuf const& streambuf)
: streambuf_ (&streambuf)
{
}
template <class Allocator>
auto
basic_streambuf<Allocator>::mutable_buffers_type::
transform::operator() (element const& e) const ->
value_type const
{
return value_type (e.data(), &e == &*std::prev(streambuf_->list_.end()) ?
streambuf_->out_end_ : e.size()) + (&e == &*streambuf_->out_ ?
streambuf_->out_pos_ : 0);
}
//------------------------------------------------------------------------------
template <class Allocator>
basic_streambuf<Allocator>::~basic_streambuf()
{
for(auto iter = list_.begin(); iter != list_.end();)
{
auto& e = *iter++;
size_type const n = e.alloc_size();
alloc_traits::destroy(this->member(), &e);
alloc_traits::deallocate(this->member(),
reinterpret_cast<char*>(&e), n);
}
}
template <class Allocator>
basic_streambuf<Allocator>::basic_streambuf(std::size_t block_size,
Allocator const& alloc)
: empty_base_optimization<Allocator>(alloc)
, block_size_ (block_size)
, block_size_next_ (block_size)
, out_ (list_.end())
{
if (! (block_size > 0))
throw std::invalid_argument(
"basic_streambuf: invalid block_size");
}
template <class Allocator>
basic_streambuf<Allocator>::basic_streambuf (basic_streambuf&& other)
: empty_base_optimization<Allocator>(other.member())
, list_ (std::move(other.list_))
, block_size_ (other.block_size_)
, block_size_next_ (other.block_size_next_)
, in_size_ (other.in_size_)
, out_ (other.out_)
, in_pos_ (other.in_pos_)
, out_pos_ (other.out_pos_)
, out_end_ (other.out_end_)
{
other.in_size_ = 0;
other.out_ = other.list_.end();
other.in_pos_ = 0;
other.out_pos_ = 0;
other.out_end_ = 0;
}
template <class Allocator>
auto
basic_streambuf<Allocator>::prepare (size_type n) ->
mutable_buffers_type
{
iterator pos = out_;
if (pos != list_.end())
{
auto const avail = pos->size() - out_pos_;
if (n > avail)
{
n -= avail;
while (++pos != list_.end())
{
if (n < pos->size())
{
out_end_ = n;
n = 0;
++pos;
break;
}
n -= pos->size();
}
}
else
{
++pos;
out_end_ = out_pos_ + n;
n = 0;
}
debug_check();
}
if (n > 0)
{
assert(pos == list_.end());
for(;;)
{
auto const avail = block_size_next_;
auto& e = *reinterpret_cast<element*>(alloc_traits::allocate(
this->member(), avail + sizeof(element)));
alloc_traits::construct(this->member(), &e, avail);
list_.push_back(e);
if (out_ == list_.end())
{
out_ = list_.iterator_to(e);
debug_check();
}
if (n <= avail)
{
out_end_ = n;
debug_check();
break;
}
n -= avail;
}
}
else
{
while (pos != list_.end())
{
auto& e = *pos++;
list_.erase(list_.iterator_to(e));
auto const len = e.alloc_size();
alloc_traits::destroy(this->member(), &e);
alloc_traits::deallocate(this->member(),
reinterpret_cast<char*>(&e), len);
}
debug_check();
}
return mutable_buffers_type (*this);
}
template <class Allocator>
void
basic_streambuf<Allocator>::commit (size_type n)
{
if (list_.empty())
return;
if (out_ == list_.end())
return;
auto const last = std::prev(list_.end());
while (out_ != last)
{
auto const avail =
out_->size() - out_pos_;
if (n < avail)
{
out_pos_ += n;
in_size_ += n;
debug_check();
return;
}
++out_;
n -= avail;
out_pos_ = 0;
in_size_ += avail;
debug_check();
}
n = std::min (n, out_end_ - out_pos_);
out_pos_ += n;
in_size_ += n;
if (out_pos_ == out_->size())
{
++out_;
out_pos_ = 0;
out_end_ = 0;
}
debug_check();
}
template <class Allocator>
auto
basic_streambuf<Allocator>::data() const ->
const_buffers_type
{
return const_buffers_type(*this);
}
template <class Allocator>
void
basic_streambuf<Allocator>::consume (size_type n)
{
if (list_.empty())
return;
auto pos = list_.begin();
for(;;)
{
if (pos != out_)
{
auto const avail = pos->size() - in_pos_;
if (n < avail)
{
in_size_ -= n;
in_pos_ += n;
debug_check();
break;
}
n -= avail;
in_size_ -= avail;
in_pos_ = 0;
debug_check();
element& e = *pos++;
list_.erase(list_.iterator_to(e));
size_type const len = e.alloc_size();
alloc_traits::destroy(this->member(), &e);
alloc_traits::deallocate(this->member(),
reinterpret_cast<char*>(&e), len);
}
else
{
auto const avail = out_pos_ - in_pos_;
if (n < avail)
{
in_size_ -= n;
in_pos_ += n;
}
else
{
in_size_ -= avail;
if (out_pos_ != out_end_||
out_ != list_.iterator_to(list_.back()))
{
in_pos_ = out_pos_;
}
else
{
// Use the whole buffer now.
// Alternatively we could deallocate it.
in_pos_ = 0;
out_pos_ = 0;
out_end_ = 0;
}
}
debug_check();
break;
}
}
}
template <class Allocator>
void
basic_streambuf<Allocator>::debug_check() const
{
#ifndef NDEBUG
if (list_.empty())
{
assert(in_pos_ == 0);
assert(in_size_ == 0);
assert(out_pos_ == 0);
assert(out_end_ == 0);
assert(out_ == list_.end());
return;
}
auto const& front = list_.front();
assert(in_pos_ < front.size());
if (out_ == list_.end())
{
assert(out_pos_ == 0);
assert(out_end_ == 0);
}
else
{
auto const& out = *out_;
auto const& back = list_.back();
assert(out_end_ <= back.size());
assert(out_pos_ < out.size());
assert(&out != &front || out_pos_ >= in_pos_);
assert(&out != &front || out_pos_ - in_pos_ == in_size_);
assert(&out != &back || out_pos_ <= out_end_);
}
#endif
}
template <class Alloc, class T>
basic_streambuf<Alloc>&
operator<< (basic_streambuf<Alloc>& buf, T const& t)
{
std::stringstream ss;
ss << t;
auto const& s = ss.str();
buf.commit(boost::asio::buffer_copy(
buf.prepare(s.size()), boost::asio::buffer(s)));
return buf;
}
//------------------------------------------------------------------------------
using streambuf = basic_streambuf<std::allocator<char>>;
/** Convert the entire basic_streambuf to a string.
@note It is more efficient to deal directly in the streambuf instead.
*/
template <class Allocator>
std::string
to_string (basic_streambuf<Allocator> const& buf)
{
std::string s;
s.resize(buf.size());
boost::asio::buffer_copy(boost::asio::buffer(
&s[0], s.size()), buf.data());
return s;
}
}
}
#endif

View File

@@ -17,30 +17,28 @@
*/
//==============================================================================
#ifndef BEAST_BOOST_GET_POINTER_H_INCLUDED
#define BEAST_BOOST_GET_POINTER_H_INCLUDED
#include <beast/asio/error.h>
#include <beast/unit_test/suite.h>
#include <string>
#include <boost/get_pointer.hpp>
// Boost 1.55 incorrectly defines BOOST_NO_CXX11_SMART_PTR
// when building with clang 3.4 and earlier. This workaround
// gives beast its own overloads.
#ifdef BOOST_NO_CXX11_SMART_PTR
#include <memory>
namespace beast {
template <class T>
T* get_pointer (std::unique_ptr<T> const& p)
{
return p.get();
}
namespace asio {
template <class T>
T* get_pointer (std::shared_ptr<T> const& p)
class error_test : public unit_test::suite
{
return p.get();
}
}
#endif
public:
void run ()
{
{
boost::system::error_code ec = boost::system::error_code (335544539,
boost::asio::error::get_ssl_category ());
std::string const s = beast::asio::asio_message (ec);
expect(s == " (20,0,219) error:140000DB:SSL routines:SSL routines:short read");
}
}
};
#endif
BEAST_DEFINE_TESTSUITE(error,asio,beast);
}
}

View File

@@ -0,0 +1,158 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
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.
*/
//==============================================================================
#include <beast/asio/streambuf.h>
#include <beast/unit_test/suite.h>
namespace beast {
namespace asio {
class streambuf_test : public unit_test::suite
{
public:
// Convert a buffer sequence to a string
template <class Buffers>
static
std::string
to_str (Buffers const& b)
{
std::string s;
auto const n = boost::asio::buffer_size(b);
s.resize(n);
boost::asio::buffer_copy(
boost::asio::buffer(&s[0], n), b);
return s;
}
// Fill a buffer sequence with predictable data
template <class Buffers>
static
void
fill (Buffers const& b)
{
char c = 0;
auto first = boost::asio::buffers_begin(b);
auto last = boost::asio::buffers_end(b);
while (first != last)
*first++ = c++;
}
// Check that a buffer sequence has predictable data
template <class Buffers>
void
check (Buffers const& b, char c = 0)
{
auto first = boost::asio::buffers_begin(b);
auto last = boost::asio::buffers_end(b);
while (first != last)
expect (*first++ == c++);
}
void
test_prepare()
{
testcase << "prepare";
beast::asio::streambuf b(11);
for (std::size_t n = 0; n < 97; ++n)
{
fill(b.prepare(n));
b.commit(n);
check(b.data());
b.consume(n);
}
}
void
test_commit()
{
testcase << "commit";
beast::asio::streambuf b(11);
for (std::size_t n = 0; n < 97; ++n)
{
fill(b.prepare(n));
char c = 0;
for (int i = 1;; ++i)
{
b.commit(i);
check(b.data(), c);
b.consume(i);
if (b.size() < 1)
break;
c += i;
}
}
}
void
test_consume()
{
testcase << "consume";
beast::asio::streambuf b(11);
for (std::size_t n = 0; n < 97; ++n)
{
fill(b.prepare(n));
b.commit(n);
char c = 0;
for (int i = 1; b.size() > 0; ++i)
{
check(b.data(), c);
b.consume(i);
c += i;
}
}
}
void run()
{
{
beast::asio::streambuf b(10);
std::string const s = "1234567890";
b << s;
expect (to_str(b.data()) == s);
b.prepare(5);
}
{
beast::asio::streambuf b(10);
b.prepare(10);
b.commit(10);
b.consume(10);
}
{
beast::asio::streambuf b(5);
boost::asio::buffer_copy(b.prepare(14),
boost::asio::buffer(std::string("1234567890ABCD")));
b.commit(4);
expect(to_str(b.data()) == "1234");
b.consume(4);
b.commit(10);
expect(to_str(b.data()) == "567890ABCD");
}
test_prepare();
test_commit();
test_consume();
}
};
BEAST_DEFINE_TESTSUITE(streambuf,asio,beast);
}
}

View File

@@ -0,0 +1,315 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
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 BEAST_ASIO_WAITABLE_EXECUTOR_H_INCLUDED
#define BEAST_ASIO_WAITABLE_EXECUTOR_H_INCLUDED
#include <boost/asio/handler_alloc_hook.hpp>
#include <boost/asio/handler_continuation_hook.hpp>
#include <boost/asio/handler_invoke_hook.hpp>
#include <condition_variable>
#include <functional>
#include <memory>
#include <mutex>
#include <beast/cxx14/type_traits.h> // <type_traits>
#include <utility>
#include <vector>
namespace beast {
namespace asio {
namespace detail {
template <class Owner, class Handler>
class waitable_executor_wrapped_handler
{
private:
static_assert (std::is_same <std::decay_t <Owner>, Owner>::value,
"Owner cannot be a const or reference type");
Handler handler_;
std::reference_wrapper <Owner> owner_;
bool cont_;
public:
waitable_executor_wrapped_handler (Owner& owner,
Handler&& handler, bool continuation = false)
: handler_ (std::move(handler))
, owner_ (owner)
{
using boost::asio::asio_handler_is_continuation;
cont_ = continuation ? true :
asio_handler_is_continuation(
std::addressof(handler_));
owner_.get().increment();
}
waitable_executor_wrapped_handler (Owner& owner,
Handler const& handler, bool continuation = false)
: handler_ (handler)
, owner_ (owner)
{
using boost::asio::asio_handler_is_continuation;
cont_ = continuation ? true :
asio_handler_is_continuation(
std::addressof(handler_));
owner_.get().increment();
}
~waitable_executor_wrapped_handler()
{
owner_.get().decrement();
}
waitable_executor_wrapped_handler (
waitable_executor_wrapped_handler const& other)
: handler_ (other.handler_)
, owner_ (other.owner_)
, cont_ (other.cont_)
{
owner_.get().increment();
}
waitable_executor_wrapped_handler (
waitable_executor_wrapped_handler&& other)
: handler_ (std::move(other.handler_))
, owner_ (other.owner_)
, cont_ (other.cont_)
{
owner_.get().increment();
}
waitable_executor_wrapped_handler& operator=(
waitable_executor_wrapped_handler const&) = delete;
template <class... Args>
void
operator()(Args&&... args)
{
handler_(std::forward<Args>(args)...);
}
template <class... Args>
void
operator()(Args&&... args) const
{
handler_(std::forward<Args>(args)...);
}
template <class Function>
friend
void
asio_handler_invoke (Function& f,
waitable_executor_wrapped_handler* h)
{
using boost::asio::asio_handler_invoke;
asio_handler_invoke(f,
std::addressof(h->handler_));
}
template <class Function>
friend
void
asio_handler_invoke (Function const& f,
waitable_executor_wrapped_handler* h)
{
using boost::asio::asio_handler_invoke;
asio_handler_invoke(f,
std::addressof(h->handler_));
}
friend
void*
asio_handler_allocate (std::size_t size,
waitable_executor_wrapped_handler* h)
{
using boost::asio::asio_handler_allocate;
return asio_handler_allocate(
size, std::addressof(h->handler_));
}
friend
void
asio_handler_deallocate (void* p, std::size_t size,
waitable_executor_wrapped_handler* h)
{
using boost::asio::asio_handler_deallocate;
asio_handler_deallocate(
p, size, std::addressof(h->handler_));
}
friend
bool
asio_handler_is_continuation (
waitable_executor_wrapped_handler* h)
{
return h->cont_;
}
};
} // detail
//------------------------------------------------------------------------------
/** Executor which provides blocking until all handlers are called. */
class waitable_executor
{
private:
template <class, class>
friend class detail::waitable_executor_wrapped_handler;
std::mutex mutex_;
std::condition_variable cond_;
std::size_t count_ = 0;
std::vector<std::function<void(void)>> notify_;
public:
/** Block until all handlers are called. */
template <class = void>
void
wait();
/** Blocks until all handlers are called or time elapses.
@return `true` if all handlers are done or `false` if the time elapses.
*/
template <class Rep, class Period>
bool
wait_for (std::chrono::duration<
Rep, Period> const& elapsed_time);
/** Blocks until all handlers are called or a time is reached.
@return `true` if all handlers are done or `false` on timeout.
*/
template <class Clock, class Duration>
bool
wait_until (std::chrono::time_point<
Clock, Duration> const& timeout_time);
/** Call a function asynchronously after all handlers are called.
The function may be called on the callers thread.
*/
template <class = void>
void
async_wait(std::function<void(void)> f);
/** Create a new handler that dispatches the wrapped handler on the Context. */
template <class Handler>
detail::waitable_executor_wrapped_handler<waitable_executor,
std::remove_reference_t<Handler>>
wrap (Handler&& handler);
private:
template <class = void>
void
increment();
template <class = void>
void
decrement();
};
template <class>
void
waitable_executor::wait()
{
std::unique_lock<std::mutex> lock(mutex_);
cond_.wait(lock,
[this]() { return count_ == 0; });
}
template <class Rep, class Period>
bool
waitable_executor::wait_for (std::chrono::duration<
Rep, Period> const& elapsed_time)
{
std::unique_lock<std::mutex> lock(mutex_);
return cond_.wait_for(lock, elapsed_time,
[this]() { return count_ == 0; }) ==
std::cv_status::no_timeout;
}
template <class Clock, class Duration>
bool
waitable_executor::wait_until (std::chrono::time_point<
Clock, Duration> const& timeout_time)
{
std::unique_lock<std::mutex> lock(mutex_);
return cond_.wait_until(lock, timeout_time,
[this]() { return count_ == 0; }) ==
std::cv_status::no_timeout;
return true;
}
template <class>
void
waitable_executor::async_wait(std::function<void(void)> f)
{
bool busy;
{
std::lock_guard<std::mutex> _(mutex_);
busy = count_ > 0;
if (busy)
notify_.emplace_back(std::move(f));
}
if (! busy)
f();
}
template <class Handler>
detail::waitable_executor_wrapped_handler<waitable_executor,
std::remove_reference_t<Handler>>
waitable_executor::wrap (Handler&& handler)
{
return detail::waitable_executor_wrapped_handler<
waitable_executor, std::remove_reference_t<Handler>>(
*this, std::forward<Handler>(handler));
}
template <class>
void
waitable_executor::increment()
{
std::lock_guard<std::mutex> _(mutex_);
++count_;
}
template <class>
void
waitable_executor::decrement()
{
bool notify;
std::vector<std::function<void(void)>> list;
{
std::lock_guard<std::mutex> _(mutex_);
notify = --count_ == 0;
if (notify)
std::swap(list, notify_);
}
if (notify)
{
cond_.notify_all();
for(auto& _ : list)
_();
}
}
} // asio
} // beast
#endif

View File

@@ -27,12 +27,12 @@ namespace beast {
/** Abstract interface to a clock.
The abstract clock interface allows a dependency injection to take
place so that the choice of implementation can be made at run-time
instead of compile time. The trade-off is that the Duration used to
represent the clock must be chosen at compile time and cannot be
changed. This includes both the choice of representation (integers
for example) and the period in ticks corresponding to one second.
This makes now() a member function instead of a static member, so
an instance of the class can be dependency injected, facilitating
unit tests where time may be controlled.
An abstract_clock inherits all the nested types of the Clock
template parameter.
Example:
@@ -40,56 +40,37 @@ namespace beast {
struct Implementation
{
abstract_clock <std::chrono::seconds>& m_clock;
// Dependency injection
//
explicit Implementation (
abstract_clock <std::chrono::seconds>& clock)
: m_clock (clock)
using clock_type = abstract_clock <std::chrono::steady_clock>;
clock_type& clock_;
explicit Implementation (clock_type& clock)
: clock_(clock)
{
}
};
@endcode
@tparam The length of time, in seconds, corresponding to one tick.
@tparam Clock A type meeting these requirements:
http://en.cppreference.com/w/cpp/concept/Clock
*/
template <class Duration>
template <class Clock>
class abstract_clock
{
public:
typedef typename Duration::rep rep;
typedef typename Duration::period period;
typedef Duration duration;
typedef std::chrono::time_point <
abstract_clock, duration> time_point;
using rep = typename Clock::rep;
using period = typename Clock::period;
using duration = typename Clock::duration;
using time_point = typename Clock::time_point;
virtual ~abstract_clock () { }
static bool const is_steady = Clock::is_steady;
/** Returns `true` if this is a steady clock. */
virtual bool is_steady () const = 0;
virtual ~abstract_clock() = default;
/** Returns the current time. */
virtual time_point now () const = 0;
#if 0
/** Convert the specified time point to a string. */
/** @{ */
//virtual std::string to_string (time_point const& tp) const = 0;
template <class Duration2>
std::string to_string (
std::chrono::time_point <abstract_clock, Duration2> const& tp) const
{
return to_string (
std::chrono::time_point_cast <Duration> (tp));
}
/** @} */
#endif
virtual time_point now() const = 0;
/** Returning elapsed ticks since the epoch. */
rep elapsed () const
rep elapsed()
{
return now().time_since_epoch().count();
}
@@ -99,68 +80,34 @@ public:
namespace detail {
template <class TrivialClock, class Duration>
struct basic_abstract_clock_wrapper : public abstract_clock <Duration>
{
using typename abstract_clock <Duration>::duration;
using typename abstract_clock <Duration>::time_point;
bool is_steady () const
{
return TrivialClock::is_steady;
}
time_point now () const
{
return time_point (duration (
std::chrono::duration_cast <duration> (
TrivialClock::now().time_since_epoch ()).count ()));
}
};
template <class TrivialClock, class Duration>
template <class Facade, class Clock>
struct abstract_clock_wrapper
: public basic_abstract_clock_wrapper <TrivialClock, Duration>
: public abstract_clock<Facade>
{
// generic conversion displays the duration
/*
std::string to_string (typename basic_abstract_clock_wrapper <
TrivialClock, Duration>::time_point const& tp) const
{
std::stringstream ss;
ss << tp.time_since_epoch();
return ss.str ();
}
*/
};
using typename abstract_clock<Facade>::duration;
using typename abstract_clock<Facade>::time_point;
/*
template <class Duration>
struct abstract_clock_wrapper <std::chrono::system_clock, Duration>
: public basic_abstract_clock_wrapper <std::chrono::system_clock, Duration>
{
typedef std::chrono::system_clock clock_type;
std::string to_string (time_point const& tp)
time_point
now() const override
{
std::stringstream ss;
ss << clock_type::time_point (tp.time_since_epoch ());
return ss.str ();
return Clock::now();
}
};
*/
}
//------------------------------------------------------------------------------
/** Retrieve a discrete clock for a type implementing the Clock concept.
The interface is created as an object with static storage duration.
/** Returns a global instance of an abstract clock.
@tparam Facade A type meeting these requirements:
http://en.cppreference.com/w/cpp/concept/Clock
@tparam Clock The actual concrete clock to use.
*/
template <class TrivialClock, class Duration>
abstract_clock <Duration>& get_abstract_clock ()
template<class Facade, class Clock = Facade>
abstract_clock<Facade>&
get_abstract_clock()
{
static detail::abstract_clock_wrapper <
TrivialClock, Duration> clock;
static detail::abstract_clock_wrapper<Facade, Clock> clock;
return clock;
}

View File

@@ -45,25 +45,25 @@ public:
class seconds_clock_thread
{
public:
typedef std::mutex mutex;
typedef std::condition_variable cond_var;
typedef std::lock_guard <mutex> lock_guard;
typedef std::unique_lock <mutex> unique_lock;
typedef std::chrono::steady_clock clock_type;
typedef std::chrono::seconds seconds;
typedef std::thread thread;
typedef std::vector <seconds_clock_worker*> workers;
using mutex = std::mutex;
using cond_var = std::condition_variable;
using lock_guard = std::lock_guard <mutex>;
using unique_lock = std::unique_lock <mutex>;
using clock_type = std::chrono::steady_clock;
using seconds = std::chrono::seconds;
using thread = std::thread;
using workers = std::vector <seconds_clock_worker*>;
bool m_stop;
mutex m_mutex;
cond_var m_cond;
workers m_workers;
thread m_thread;
bool stop_;
mutex mutex_;
cond_var cond_;
workers workers_;
thread thread_;
seconds_clock_thread ()
: m_stop (false)
: stop_ (false)
{
m_thread = thread (std::bind(
thread_ = thread (std::bind(
&seconds_clock_thread::run, this));
}
@@ -74,37 +74,37 @@ public:
void add (seconds_clock_worker& w)
{
lock_guard lock (m_mutex);
m_workers.push_back (&w);
lock_guard lock (mutex_);
workers_.push_back (&w);
}
void remove (seconds_clock_worker& w)
{
lock_guard lock (m_mutex);
m_workers.erase (std::find (
m_workers.begin (), m_workers.end(), &w));
lock_guard lock (mutex_);
workers_.erase (std::find (
workers_.begin (), workers_.end(), &w));
}
void stop()
{
if (m_thread.joinable())
if (thread_.joinable())
{
{
lock_guard lock (m_mutex);
m_stop = true;
lock_guard lock (mutex_);
stop_ = true;
}
m_cond.notify_all();
m_thread.join();
cond_.notify_all();
thread_.join();
}
}
void run()
{
unique_lock lock (m_mutex);;
unique_lock lock (mutex_);;
for (;;)
{
for (auto iter : m_workers)
for (auto iter : workers_)
iter->sample();
clock_type::time_point const when (
@@ -112,7 +112,7 @@ public:
clock_type::now().time_since_epoch()) +
seconds (1));
if (m_cond.wait_until (lock, when, [this]{ return m_stop; }))
if (cond_.wait_until (lock, when, [this]{ return stop_; }))
return;
}
}
@@ -143,24 +143,26 @@ basic_seconds_clock_main_hook()
}
/** A clock whose minimum resolution is one second.
The purpose of this class is to optimize the performance of the now()
member function call. It uses a dedicated thread that wakes up at least
once per second to sample the requested trivial clock.
@tparam TrivialClock The clock to sample.
@tparam Clock A type meeting these requirements:
http://en.cppreference.com/w/cpp/concept/Clock
*/
template <class TrivialClock>
template <class Clock>
class basic_seconds_clock
{
public:
typedef std::chrono::seconds resolution;
typedef typename resolution::rep rep;
typedef typename resolution::period period;
typedef std::chrono::duration <rep, period> duration;
typedef std::chrono::time_point <basic_seconds_clock> time_point;
using rep = typename Clock::rep;
using period = typename Clock::period;
using duration = typename Clock::duration;
using time_point = typename Clock::time_point;
static bool const is_steady = TrivialClock::is_steady;
static bool const is_steady = Clock::is_steady;
static time_point now ()
static time_point now()
{
// Make sure the thread is constructed before the
// worker otherwise we will crash during destruction
@@ -176,45 +178,36 @@ public:
struct worker : detail::seconds_clock_worker
{
typedef std::mutex mutex;
typedef std::lock_guard <mutex> lock_guard;
time_point m_now;
mutex m_mutex;
std::mutex mutex_;
static time_point get_now ()
worker()
: m_now(Clock::now())
{
return time_point (floor <resolution> (
TrivialClock::now().time_since_epoch()));
detail::seconds_clock_thread::instance().add(*this);
}
worker ()
: m_now (get_now ())
~worker()
{
detail::seconds_clock_thread::instance().add (*this);
}
~worker ()
{
detail::seconds_clock_thread::instance().remove (*this);
detail::seconds_clock_thread::instance().remove(*this);
}
time_point now()
{
lock_guard lock (m_mutex);
std::lock_guard<std::mutex> lock (mutex_);
return m_now;
}
void sample ()
void sample()
{
lock_guard lock (m_mutex);
m_now = get_now ();
std::lock_guard<std::mutex> lock (mutex_);
m_now = Clock::now();
}
};
static worker w;
return w.now ();
return w.now();
}
};

View File

@@ -32,8 +32,6 @@
#include <beast/utility/noexcept.h>
#include <ctime>
#include <locale>
#define BEAST_CHRONO_NO_TIMEPOINT_IO 1
/*
@@ -798,292 +796,8 @@ time_fmt(timezone f)
return __time_man(f);
}
#if ! BEAST_CHRONO_NO_TIMEPOINT_IO
} // chrono
template <class _CharT, class _Traits, class _Duration>
basic_istream<_CharT, _Traits>&
operator>>(basic_istream<_CharT, _Traits>& __is,
time_point<steady_clock, _Duration>& __tp)
{
_Duration __d;
__is >> __d;
if (__is.good())
{
const _CharT __u[] = {' ', 's', 'i', 'n', 'c', 'e', ' ', 'b', 'o', 'o', 't'};
const basic_string<_CharT> __units(__u, __u + sizeof(__u)/sizeof(__u[0]));
ios_base::iostate __err = ios_base::goodbit;
typedef istreambuf_iterator<_CharT, _Traits> _I;
_I __i(__is);
_I __e;
ptrdiff_t __k = __scan_keyword(__i, __e,
&__units, &__units + 1,
use_facet<ctype<_CharT> >(__is.getloc()),
__err) - &__units;
if (__k == 1)
{
// failed to read epoch string
__is.setstate(__err);
return __is;
}
__tp = time_point<steady_clock, _Duration>(__d);
}
else
__is.setstate(__is.failbit);
return __is;
}
template <class _CharT, class _Traits, class _Duration>
basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __os,
const time_point<system_clock, _Duration>& __tp)
{
typename basic_ostream<_CharT, _Traits>::sentry ok(__os);
if (ok)
{
bool failed = false;
try
{
const _CharT* pb = nullptr;
const _CharT* pe = pb;
timezone tz = utc;
typedef timepunct<_CharT> F;
locale loc = __os.getloc();
if (has_facet<F>(loc))
{
const F& f = use_facet<F>(loc);
pb = f.fmt().data();
pe = pb + f.fmt().size();
tz = f.get_timezone();
}
time_t __t = system_clock::to_time_t(__tp);
tm __tm;
if (tz == local)
{
if (localtime_r(&__t, &__tm) == 0)
failed = true;
}
else
{
if (gmtime_r(&__t, &__tm) == 0)
failed = true;
}
if (!failed)
{
const time_put<_CharT>& tp = use_facet<time_put<_CharT> >(loc);
if (pb == pe)
{
_CharT pattern[] = {'%', 'F', 'T', '%', 'H', ':', '%', 'M', ':'};
pb = pattern;
pe = pb + sizeof(pattern) / sizeof(_CharT);
failed = tp.put(__os, __os, __os.fill(), &__tm, pb, pe).failed();
if (!failed)
{
duration<double> __d = __tp - system_clock::from_time_t(__t) +
seconds(__tm.tm_sec);
if (__d.count() < 10)
__os << _CharT('0');
ios::fmtflags __flgs = __os.flags();
__os.setf(ios::fixed, ios::floatfield);
__os << __d.count();
__os.flags(__flgs);
if (tz == local)
{
_CharT sub_pattern[] = {' ', '%', 'z'};
pb = sub_pattern;
pe = pb + + sizeof(sub_pattern) / sizeof(_CharT);
failed = tp.put(__os, __os, __os.fill(), &__tm, pb, pe).failed();
}
else
{
_CharT sub_pattern[] = {' ', '+', '0', '0', '0', '0', 0};
__os << sub_pattern;
}
}
}
else
failed = tp.put(__os, __os, __os.fill(), &__tm, pb, pe).failed();
}
}
catch (...)
{
failed = true;
}
if (failed)
__os.setstate(ios_base::failbit | ios_base::badbit);
}
return __os;
}
template <class _CharT, class _InputIterator>
minutes
__extract_z(_InputIterator& __b, _InputIterator __e,
ios_base::iostate& __err, const ctype<_CharT>& __ct)
{
int __minn = 0;
if (__b != __e)
{
char __cn = __ct.narrow(*__b, 0);
if (__cn != '+' && __cn != '-')
{
__err |= ios_base::failbit;
return minutes(0);
}
int __sn = __cn == '-' ? -1 : 1;
int __hr = 0;
for (int i = 0; i < 2; ++i)
{
if (++__b == __e)
{
__err |= ios_base::eofbit | ios_base::failbit;
return minutes(0);
}
__cn = __ct.narrow(*__b, 0);
if (!('0' <= __cn && __cn <= '9'))
{
__err |= ios_base::failbit;
return minutes(0);
}
__hr = __hr * 10 + __cn - '0';
}
for (int i = 0; i < 2; ++i)
{
if (++__b == __e)
{
__err |= ios_base::eofbit | ios_base::failbit;
return minutes(0);
}
__cn = __ct.narrow(*__b, 0);
if (!('0' <= __cn && __cn <= '9'))
{
__err |= ios_base::failbit;
return minutes(0);
}
__minn = __minn * 10 + __cn - '0';
}
if (++__b == __e)
__err |= ios_base::eofbit;
__minn += __hr * 60;
__minn *= __sn;
}
else
__err |= ios_base::eofbit | ios_base::failbit;
return minutes(__minn);
}
template <class _CharT, class _Traits, class _Duration>
basic_istream<_CharT, _Traits>&
operator>>(basic_istream<_CharT, _Traits>& __is,
time_point<system_clock, _Duration>& __tp)
{
typename basic_istream<_CharT,_Traits>::sentry ok(__is);
if (ok)
{
ios_base::iostate err = ios_base::goodbit;
try
{
const _CharT* pb = nullptr;
const _CharT* pe = pb;
typedef timepunct<_CharT> F;
locale loc = __is.getloc();
timezone tz = utc;
if (has_facet<F>(loc))
{
const F& f = use_facet<F>(loc);
pb = f.fmt().data();
pe = pb + f.fmt().size();
tz = f.get_timezone();
}
const time_get<_CharT>& tg = use_facet<time_get<_CharT> >(loc);
const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(loc);
tm __tm = {0};
typedef istreambuf_iterator<_CharT, _Traits> _I;
if (pb == pe)
{
_CharT pattern[] = {'%', 'Y', '-', '%', 'm', '-', '%', 'd',
'T', '%', 'H', ':', '%', 'M', ':'};
pb = pattern;
pe = pb + sizeof(pattern) / sizeof(_CharT);
tg.get(__is, 0, __is, err, &__tm, pb, pe);
if (err & ios_base::failbit)
goto __exit;
double __sec;
_CharT __c = _CharT();
__is >> __sec;
if (__is.fail())
{
err |= ios_base::failbit;
goto __exit;
}
_I __i(__is);
_I __eof;
__c = *__i;
if (++__i == __eof || __c != ' ')
{
err |= ios_base::failbit;
goto __exit;
}
minutes __minn = __extract_z(__i, __eof, err, __ct);
if (err & ios_base::failbit)
goto __exit;
time_t __t;
__t = timegm(&__tm);
__tp = system_clock::from_time_t(__t) - __minn
+ round<microseconds>(duration<double>(__sec));
}
else
{
const _CharT __z[2] = {'%', 'z'};
const _CharT* __fz = std::search(pb, pe, __z, __z+2);
tg.get(__is, 0, __is, err, &__tm, pb, __fz);
minutes __minn(0);
if (__fz != pe)
{
if (err != ios_base::goodbit)
{
err |= ios_base::failbit;
goto __exit;
}
_I __i(__is);
_I __eof;
__minn = __extract_z(__i, __eof, err, __ct);
if (err & ios_base::failbit)
goto __exit;
if (__fz+2 != pe)
{
if (err != ios_base::goodbit)
{
err |= ios_base::failbit;
goto __exit;
}
tg.get(__is, 0, __is, err, &__tm, __fz+2, pe);
if (err & ios_base::failbit)
goto __exit;
}
}
__tm.tm_isdst = -1;
time_t __t;
if (tz == utc || __fz != pe)
__t = timegm(&__tm);
else
__t = mktime(&__tm);
__tp = system_clock::from_time_t(__t) - __minn;
}
}
catch (...)
{
err |= ios_base::badbit | ios_base::failbit;
}
__exit:
__is.setstate(err);
}
return __is;
}
#endif
} // chrono
//_LIBCPP_END_NAMESPACE_STD
}
#endif

View File

@@ -17,8 +17,8 @@
*/
//==============================================================================
#ifndef BEAST_CHRONO_UTIL_H_INCLUDED
#define BEAST_CHRONO_UTIL_H_INCLUDED
#ifndef BEAST_CHRONO_CHRONO_UTIL_H_INCLUDED
#define BEAST_CHRONO_CHRONO_UTIL_H_INCLUDED
// From Howard Hinnant
// http://home.roadrunner.com/~hinnant/duration_io/chrono_util.html

View File

@@ -25,68 +25,73 @@
namespace beast {
/** Manual clock implementation.
This concrete class implements the @ref abstract_clock interface and
allows the time to be advanced manually, mainly for the purpose of
providing a clock in unit tests.
@tparam The length of time, in seconds, corresponding to one tick.
@tparam Clock A type meeting these requirements:
http://en.cppreference.com/w/cpp/concept/Clock
*/
template <class Duration, bool IsSteady = true>
class manual_clock : public abstract_clock <Duration>
template <class Clock>
class manual_clock
: public abstract_clock<Clock>
{
public:
using typename abstract_clock <Duration>::rep;
using typename abstract_clock <Duration>::duration;
using typename abstract_clock <Duration>::time_point;
explicit manual_clock (time_point const& t = time_point (Duration (0)))
: m_now (t)
{
}
bool is_steady () const
{
return IsSteady;
}
time_point now () const
{
return m_now;
}
#if 0
std::string to_string (time_point const& tp) const
{
std::stringstream ss;
ss << tp.time_since_epoch() << " from start";
return ss.str ();
}
#endif
/** Set the current time of the manual clock.
Precondition:
! IsSteady || t > now()
*/
void set (time_point const& t)
{
//if (IsSteady)
m_now = t;
}
/** Convenience for setting the time using a duration in @ref rep units. */
void set (rep v)
{
set (time_point (duration (v)));
}
/** Convenience for advancing the clock by one. */
manual_clock& operator++ ()
{
m_now += duration (1);
return *this;
}
using typename abstract_clock<Clock>::rep;
using typename abstract_clock<Clock>::duration;
using typename abstract_clock<Clock>::time_point;
private:
time_point m_now;
time_point now_;
public:
explicit
manual_clock (time_point const& now = time_point(duration(0)))
: now_(now)
{
}
time_point
now() const override
{
return now_;
}
/** Set the current time of the manual clock. */
void
set (time_point const& when)
{
assert(! Clock::is_steady || when >= now_);
now_ = when;
}
/** Convenience for setting the time in seconds from epoch. */
template <class Integer>
void
set(Integer seconds_from_epoch)
{
set(time_point(duration(
std::chrono::seconds(seconds_from_epoch))));
}
/** Advance the clock by a duration. */
template <class Rep, class Period>
void
advance(std::chrono::duration<Rep, Period> const& elapsed)
{
assert(! Clock::is_steady ||
(now_ + elapsed) >= now_);
now_ += elapsed;
}
/** Convenience for advancing the clock by one second. */
manual_clock&
operator++ ()
{
advance(std::chrono::seconds(1));
return *this;
}
};
}

View File

@@ -20,11 +20,8 @@
// MODULES: ../impl/chrono_io.cpp
#include <beast/chrono/abstract_clock.h>
#include <beast/chrono/abstract_clock_io.h>
#include <beast/chrono/manual_clock.h>
#include <beast/unit_test/suite.h>
#include <sstream>
#include <string>
#include <thread>
@@ -34,7 +31,8 @@ namespace beast {
class abstract_clock_test : public unit_test::suite
{
public:
void test (abstract_clock <std::chrono::seconds>& c)
template <class Clock>
void test (abstract_clock<Clock>& c)
{
{
auto const t1 (c.now ());
@@ -53,18 +51,18 @@ public:
void test_manual ()
{
typedef manual_clock <std::chrono::seconds> clock_type;
using clock_type = manual_clock<std::chrono::steady_clock>;
clock_type c;
std::stringstream ss;
ss << "now() = " << c.now () << std::endl;
ss << "now() = " << c.now().time_since_epoch() << std::endl;
c.set (clock_type::time_point (std::chrono::seconds (1)));
ss << "now() = " << c.now () << std::endl;
c.set (clock_type::time_point (std::chrono::seconds(1)));
ss << "now() = " << c.now().time_since_epoch() << std::endl;
c.set (clock_type::time_point (std::chrono::seconds (2)));
ss << "now() = " << c.now () << std::endl;
c.set (clock_type::time_point (std::chrono::seconds(2)));
ss << "now() = " << c.now().time_since_epoch() << std::endl;
log << ss.str();
}
@@ -72,16 +70,16 @@ public:
void run ()
{
log << "steady_clock";
test (get_abstract_clock <std::chrono::steady_clock,
std::chrono::seconds> ());
test (get_abstract_clock<
std::chrono::steady_clock>());
log << "system_clock";
test (get_abstract_clock <std::chrono::system_clock,
std::chrono::seconds> ());
test (get_abstract_clock<
std::chrono::system_clock>());
log << "high_resolution_clock";
test (get_abstract_clock <std::chrono::high_resolution_clock,
std::chrono::seconds> ());
test (get_abstract_clock<
std::chrono::high_resolution_clock>());
log << "manual_clock";
test_manual ();
@@ -90,6 +88,6 @@ public:
}
};
BEAST_DEFINE_TESTSUITE(abstract_clock,chrono,beast);
BEAST_DEFINE_TESTSUITE_MANUAL(abstract_clock,chrono,beast);
}

View File

@@ -44,10 +44,6 @@
#define BEAST_DISABLE_CONTRACT_CHECKS 0
#endif
#ifndef BEAST_COMPILER_CHECKS_SOCKET_OVERRIDES
#define BEAST_COMPILER_CHECKS_SOCKET_OVERRIDES 0
#endif
//------------------------------------------------------------------------------
#ifndef BEAST_DONT_AUTOLINK_TO_WIN32_LIBRARIES

View File

@@ -20,6 +20,9 @@
// Ideas from boost
// Intel
#ifndef BEAST_CONFIG_SELECTCOMPILERCONFIG_H_INCLUDED
#define BEAST_CONFIG_SELECTCOMPILERCONFIG_H_INCLUDED
#if defined(__INTEL_COMPILER) || defined(__ICL) || defined(__ICC) || defined(__ECC)
#define BEAST_COMPILER_CONFIG "config/compiler/Intel.h"
@@ -42,3 +45,4 @@
#error "Unsupported compiler."
#endif
#endif

View File

@@ -20,6 +20,9 @@
// Ideas from boost
// Android, which must be manually set by defining BEAST_ANDROID
#ifndef BEAST_CONFIG_SELECTPLATFORMCONFIG_H_INCLUDED
#define BEAST_CONFIG_SELECTPLATFORMCONFIG_H_INCLUDED
#if defined(BEAST_ANDROID)
#define BEAST_PLATFORM_CONFIG "config/platform/Android.h"
@@ -42,3 +45,4 @@
#else
#error "Unsupported platform."
#endif
#endif

View File

@@ -19,4 +19,8 @@
// Microsoft Visual C++ compiler configuration
#ifndef BEAST_CONFIG_COMPILER_VISUALC_H_INCLUDED
#define BEAST_CONFIG_COMPILER_VISUALC_H_INCLUDED
#include <beast/utility/noexcept.h>
#endif

View File

@@ -19,8 +19,12 @@
// Android platform configuration
#ifndef BEAST_CONFIG_PLATFORM_ANDROID_H_INCLUDED
#define BEAST_CONFIG_PLATFORM_ANDROID_H_INCLUDED
#ifdef BEAST_ANDROID
#undef BEAST_ANDROID
#endif
#define BEAST_ANDROID 1
#endif

View File

@@ -21,10 +21,4 @@
#include <BeastConfig.h>
#endif
#include <beast/container/impl/spookyv2.cpp>
#include <beast/container/impl/siphash.cpp>
#include <beast/container/tests/aged_associative_container.test.cpp>
#include <beast/container/tests/buffer_view.test.cpp>
#include <beast/container/tests/hardened_hash.test.cpp>
#include <beast/container/tests/hash_append.test.cpp>

View File

@@ -31,12 +31,12 @@ namespace beast {
template <
class Key,
class T,
class Duration = std::chrono::seconds,
class Clock = std::chrono::steady_clock,
class Compare = std::less <Key>,
class Allocator = std::allocator <std::pair <Key const, T>>
>
using aged_map = detail::aged_ordered_container <
false, true, Key, T, Duration, Compare, Allocator>;
false, true, Key, T, Clock, Compare, Allocator>;
}

View File

@@ -31,12 +31,12 @@ namespace beast {
template <
class Key,
class T,
class Duration = std::chrono::seconds,
class Clock = std::chrono::steady_clock,
class Compare = std::less <Key>,
class Allocator = std::allocator <std::pair <Key const, T>>
>
using aged_multimap = detail::aged_ordered_container <
true, true, Key, T, Duration, Compare, Allocator>;
true, true, Key, T, Clock, Compare, Allocator>;
}

View File

@@ -30,12 +30,12 @@ namespace beast {
template <
class Key,
class Duration = std::chrono::seconds,
class Clock = std::chrono::steady_clock,
class Compare = std::less <Key>,
class Allocator = std::allocator <Key>
>
using aged_multiset = detail::aged_ordered_container <
true, false, Key, void, Duration, Compare, Allocator>;
true, false, Key, void, Clock, Compare, Allocator>;
}

View File

@@ -30,12 +30,12 @@ namespace beast {
template <
class Key,
class Duration = std::chrono::seconds,
class Clock = std::chrono::steady_clock,
class Compare = std::less <Key>,
class Allocator = std::allocator <Key>
>
using aged_set = detail::aged_ordered_container <
false, false, Key, void, Duration, Compare, Allocator>;
false, false, Key, void, Clock, Compare, Allocator>;
}

View File

@@ -31,13 +31,13 @@ namespace beast {
template <
class Key,
class T,
class Duration = std::chrono::seconds,
class Clock = std::chrono::steady_clock,
class Hash = std::hash <Key>,
class KeyEqual = std::equal_to <Key>,
class Allocator = std::allocator <std::pair <Key const, T>>
>
using aged_unordered_map = detail::aged_unordered_container <
false, true, Key, T, Duration, Hash, KeyEqual, Allocator>;
false, true, Key, T, Clock, Hash, KeyEqual, Allocator>;
}

View File

@@ -31,13 +31,13 @@ namespace beast {
template <
class Key,
class T,
class Duration = std::chrono::seconds,
class Clock = std::chrono::steady_clock,
class Hash = std::hash <Key>,
class KeyEqual = std::equal_to <Key>,
class Allocator = std::allocator <std::pair <Key const, T>>
>
using aged_unordered_multimap = detail::aged_unordered_container <
true, true, Key, T, Duration, Hash, KeyEqual, Allocator>;
true, true, Key, T, Clock, Hash, KeyEqual, Allocator>;
}

View File

@@ -30,13 +30,13 @@ namespace beast {
template <
class Key,
class Duration = std::chrono::seconds,
class Clock = std::chrono::steady_clock,
class Hash = std::hash <Key>,
class KeyEqual = std::equal_to <Key>,
class Allocator = std::allocator <Key>
>
using aged_unordered_multiset = detail::aged_unordered_container <
true, false, Key, void, Duration, Hash, KeyEqual, Allocator>;
true, false, Key, void, Clock, Hash, KeyEqual, Allocator>;
}

View File

@@ -30,13 +30,13 @@ namespace beast {
template <
class Key,
class Duration = std::chrono::seconds,
class Clock = std::chrono::steady_clock,
class Hash = std::hash <Key>,
class KeyEqual = std::equal_to <Key>,
class Allocator = std::allocator <Key>
>
using aged_unordered_set = detail::aged_unordered_container <
false, false, Key, void, Duration, Hash, KeyEqual, Allocator>;
false, false, Key, void, Clock, Hash, KeyEqual, Allocator>;
}

View File

@@ -27,8 +27,8 @@
*/
//==============================================================================
#ifndef BEAST_CYCLIC_ITERATOR_H_INCLUDED
#define BEAST_CYCLIC_ITERATOR_H_INCLUDED
#ifndef BEAST_CONTAINER_CYCLIC_ITERATOR_H_INCLUDED
#define BEAST_CONTAINER_CYCLIC_ITERATOR_H_INCLUDED
#include <iterator>
#include <boost/iterator/iterator_facade.hpp>

View File

@@ -17,8 +17,8 @@
*/
//==============================================================================
#ifndef BEAST_CONTAINER_AGED_ASSOCIATIVE_CONTAINER_H_INCLUDED
#define BEAST_CONTAINER_AGED_ASSOCIATIVE_CONTAINER_H_INCLUDED
#ifndef BEAST_CONTAINER_DETAIL_AGED_ASSOCIATIVE_CONTAINER_H_INCLUDED
#define BEAST_CONTAINER_DETAIL_AGED_ASSOCIATIVE_CONTAINER_H_INCLUDED
#include <type_traits>

View File

@@ -17,8 +17,8 @@
*/
//==============================================================================
#ifndef BEAST_CONTAINER_AGED_CONTAINER_ITERATOR_H_INCLUDED
#define BEAST_CONTAINER_AGED_CONTAINER_ITERATOR_H_INCLUDED
#ifndef BEAST_CONTAINER_DETAIL_AGED_CONTAINER_ITERATOR_H_INCLUDED
#define BEAST_CONTAINER_DETAIL_AGED_CONTAINER_ITERATOR_H_INCLUDED
#include <iterator>
#include <type_traits>
@@ -49,7 +49,7 @@ class aged_container_iterator
: public Base
{
public:
typedef typename Iterator::value_type::stashed::time_point time_point;
using time_point = typename Iterator::value_type::stashed::time_point;
// Could be '= default', but Visual Studio 2013 chokes on it [Aug 2014]
aged_container_iterator ()

View File

@@ -17,20 +17,17 @@
*/
//==============================================================================
#ifndef BEAST_CONTAINER_AGED_ORDERED_CONTAINER_H_INCLUDED
#define BEAST_CONTAINER_AGED_ORDERED_CONTAINER_H_INCLUDED
#ifndef BEAST_CONTAINER_DETAIL_AGED_ORDERED_CONTAINER_H_INCLUDED
#define BEAST_CONTAINER_DETAIL_AGED_ORDERED_CONTAINER_H_INCLUDED
#include <beast/container/detail/aged_container_iterator.h>
#include <beast/container/detail/aged_associative_container.h>
#include <beast/container/aged_container.h>
#include <beast/chrono/abstract_clock.h>
#include <beast/utility/empty_base_optimization.h>
#include <boost/intrusive/list.hpp>
#include <boost/intrusive/set.hpp>
#include <boost/version.hpp>
#include <beast/cxx14/algorithm.h> // <algorithm>
#include <functional>
#include <initializer_list>
@@ -49,10 +46,17 @@ struct is_boost_reverse_iterator
: std::false_type
{};
#if BOOST_VERSION >= 105800
template <class It>
struct is_boost_reverse_iterator<boost::intrusive::reverse_iterator<It>>
: std::true_type
{};
#else
template <class It>
struct is_boost_reverse_iterator<boost::intrusive::detail::reverse_iterator<It>>
: std::true_type
{};
#endif
/** Associative container where each element is also indexed by time.
@@ -75,7 +79,7 @@ template <
bool IsMap,
class Key,
class T,
class Duration = std::chrono::seconds,
class Clock = std::chrono::steady_clock,
class Compare = std::less <Key>,
class Allocator = std::allocator <
typename std::conditional <IsMap,
@@ -85,25 +89,20 @@ template <
class aged_ordered_container
{
public:
typedef abstract_clock <Duration> clock_type;
typedef typename clock_type::time_point time_point;
typedef typename clock_type::duration duration;
typedef Key key_type;
typedef T mapped_type;
typedef typename std::conditional <
IsMap,
std::pair <Key const, T>,
Key>::type value_type;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
using clock_type = abstract_clock<Clock>;
using time_point = typename clock_type::time_point;
using duration = typename clock_type::duration;
using key_type = Key;
using mapped_type = T;
using value_type = typename std::conditional <
IsMap, std::pair <Key const, T>, Key>::type;
using size_type = std::size_t;
using difference_type = std::ptrdiff_t;
// Introspection (for unit tests)
typedef std::false_type is_unordered;
typedef std::integral_constant <bool, IsMulti> is_multi;
typedef std::integral_constant <bool, IsMap> is_map;
// VFALCO TODO How can we reorder the declarations to keep
// all the public things together contiguously?
using is_unordered = std::false_type;
using is_multi = std::integral_constant <bool, IsMulti>;
using is_map = std::integral_constant <bool, IsMap>;
private:
static Key const& extract (value_type const& value)
@@ -126,8 +125,8 @@ private:
// need to see the container declaration.
struct stashed
{
typedef typename aged_ordered_container::value_type value_type;
typedef typename aged_ordered_container::time_point time_point;
using value_type = typename aged_ordered_container::value_type;
using time_point = typename aged_ordered_container::time_point;
};
element (
@@ -244,11 +243,10 @@ private:
}
};
typedef typename boost::intrusive::make_list <element,
boost::intrusive::constant_time_size <false>
>::type list_type;
using list_type = typename boost::intrusive::make_list <element,
boost::intrusive::constant_time_size <false>>::type;
typedef typename std::conditional <
using cont_type = typename std::conditional <
IsMulti,
typename boost::intrusive::make_multiset <element,
boost::intrusive::constant_time_size <true>
@@ -256,10 +254,10 @@ private:
typename boost::intrusive::make_set <element,
boost::intrusive::constant_time_size <true>
>::type
>::type cont_type;
>::type;
typedef typename std::allocator_traits <
Allocator>::template rebind_alloc <element> ElementAllocator;
using ElementAllocator = typename std::allocator_traits <
Allocator>::template rebind_alloc <element>;
using ElementAllocatorTraits = std::allocator_traits <ElementAllocator>;
@@ -427,29 +425,29 @@ private:
}
public:
typedef Compare key_compare;
typedef typename std::conditional <
using key_compare = Compare;
using value_compare = typename std::conditional <
IsMap,
pair_value_compare,
Compare>::type value_compare;
typedef Allocator allocator_type;
typedef value_type& reference;
typedef value_type const& const_reference;
typedef typename std::allocator_traits <
Allocator>::pointer pointer;
typedef typename std::allocator_traits <
Allocator>::const_pointer const_pointer;
Compare>::type;
using allocator_type = Allocator;
using reference = value_type&;
using const_reference = value_type const&;
using pointer = typename std::allocator_traits <
Allocator>::pointer;
using const_pointer = typename std::allocator_traits <
Allocator>::const_pointer;
// A set (that is, !IsMap) iterator is aways const because the elements
// of a set are immutable.
typedef detail::aged_container_iterator <!IsMap,
typename cont_type::iterator> iterator;
typedef detail::aged_container_iterator <true,
typename cont_type::iterator> const_iterator;
typedef detail::aged_container_iterator <!IsMap,
typename cont_type::reverse_iterator> reverse_iterator;
typedef detail::aged_container_iterator <true,
typename cont_type::reverse_iterator> const_reverse_iterator;
// A set iterator (IsMap==false) is always const
// because the elements of a set are immutable.
using iterator = detail::aged_container_iterator<
! IsMap, typename cont_type::iterator>;
using const_iterator = detail::aged_container_iterator<
true, typename cont_type::iterator>;
using reverse_iterator = detail::aged_container_iterator<
! IsMap, typename cont_type::reverse_iterator>;
using const_reverse_iterator = detail::aged_container_iterator<
true, typename cont_type::reverse_iterator>;
//--------------------------------------------------------------------------
//
@@ -463,16 +461,16 @@ public:
class chronological_t
{
public:
// A set (that is, !IsMap) iterator is aways const because the elements
// of a set are immutable.
typedef detail::aged_container_iterator <!IsMap,
typename list_type::iterator> iterator;
typedef detail::aged_container_iterator <true,
typename list_type::iterator> const_iterator;
typedef detail::aged_container_iterator <!IsMap,
typename list_type::reverse_iterator> reverse_iterator;
typedef detail::aged_container_iterator <true,
typename list_type::reverse_iterator> const_reverse_iterator;
// A set iterator (IsMap==false) is always const
// because the elements of a set are immutable.
using iterator = detail::aged_container_iterator<
! IsMap, typename list_type::iterator>;
using const_iterator = detail::aged_container_iterator<
true, typename list_type::iterator>;
using reverse_iterator = detail::aged_container_iterator<
! IsMap, typename list_type::reverse_iterator>;
using const_reverse_iterator = detail::aged_container_iterator<
true, typename list_type::reverse_iterator>;
iterator begin ()
{
@@ -570,6 +568,8 @@ public:
//
//--------------------------------------------------------------------------
aged_ordered_container() = delete;
explicit aged_ordered_container (clock_type& clock);
aged_ordered_container (clock_type& clock,
@@ -1237,8 +1237,8 @@ private:
//------------------------------------------------------------------------------
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
class Clock, class Compare, class Allocator>
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
aged_ordered_container (
clock_type& clock)
: m_config (clock)
@@ -1246,8 +1246,8 @@ aged_ordered_container (
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
class Clock, class Compare, class Allocator>
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
aged_ordered_container (
clock_type& clock,
Compare const& comp)
@@ -1256,8 +1256,8 @@ aged_ordered_container (
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
class Clock, class Compare, class Allocator>
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
aged_ordered_container (
clock_type& clock,
Allocator const& alloc)
@@ -1266,8 +1266,8 @@ aged_ordered_container (
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
class Clock, class Compare, class Allocator>
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
aged_ordered_container (
clock_type& clock,
Compare const& comp,
@@ -1277,9 +1277,9 @@ aged_ordered_container (
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
class Clock, class Compare, class Allocator>
template <class InputIt>
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
aged_ordered_container (InputIt first, InputIt last,
clock_type& clock)
: m_config (clock)
@@ -1288,9 +1288,9 @@ aged_ordered_container (InputIt first, InputIt last,
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
class Clock, class Compare, class Allocator>
template <class InputIt>
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
aged_ordered_container (InputIt first, InputIt last,
clock_type& clock,
Compare const& comp)
@@ -1300,9 +1300,9 @@ aged_ordered_container (InputIt first, InputIt last,
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
class Clock, class Compare, class Allocator>
template <class InputIt>
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
aged_ordered_container (InputIt first, InputIt last,
clock_type& clock,
Allocator const& alloc)
@@ -1312,9 +1312,9 @@ aged_ordered_container (InputIt first, InputIt last,
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
class Clock, class Compare, class Allocator>
template <class InputIt>
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
aged_ordered_container (InputIt first, InputIt last,
clock_type& clock,
Compare const& comp,
@@ -1325,8 +1325,8 @@ aged_ordered_container (InputIt first, InputIt last,
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
class Clock, class Compare, class Allocator>
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
aged_ordered_container (aged_ordered_container const& other)
: m_config (other.m_config)
{
@@ -1334,8 +1334,8 @@ aged_ordered_container (aged_ordered_container const& other)
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
class Clock, class Compare, class Allocator>
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
aged_ordered_container (aged_ordered_container const& other,
Allocator const& alloc)
: m_config (other.m_config, alloc)
@@ -1344,8 +1344,8 @@ aged_ordered_container (aged_ordered_container const& other,
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
class Clock, class Compare, class Allocator>
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
aged_ordered_container (aged_ordered_container&& other)
: m_config (std::move (other.m_config))
, m_cont (std::move (other.m_cont))
@@ -1354,8 +1354,8 @@ aged_ordered_container (aged_ordered_container&& other)
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
class Clock, class Compare, class Allocator>
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
aged_ordered_container (aged_ordered_container&& other,
Allocator const& alloc)
: m_config (std::move (other.m_config), alloc)
@@ -1365,8 +1365,8 @@ aged_ordered_container (aged_ordered_container&& other,
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
class Clock, class Compare, class Allocator>
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
aged_ordered_container (std::initializer_list <value_type> init,
clock_type& clock)
: m_config (clock)
@@ -1375,8 +1375,8 @@ aged_ordered_container (std::initializer_list <value_type> init,
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
class Clock, class Compare, class Allocator>
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
aged_ordered_container (std::initializer_list <value_type> init,
clock_type& clock,
Compare const& comp)
@@ -1386,8 +1386,8 @@ aged_ordered_container (std::initializer_list <value_type> init,
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
class Clock, class Compare, class Allocator>
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
aged_ordered_container (std::initializer_list <value_type> init,
clock_type& clock,
Allocator const& alloc)
@@ -1397,8 +1397,8 @@ aged_ordered_container (std::initializer_list <value_type> init,
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
class Clock, class Compare, class Allocator>
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
aged_ordered_container (std::initializer_list <value_type> init,
clock_type& clock,
Compare const& comp,
@@ -1409,17 +1409,17 @@ aged_ordered_container (std::initializer_list <value_type> init,
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
class Clock, class Compare, class Allocator>
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
~aged_ordered_container()
{
clear();
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
class Clock, class Compare, class Allocator>
auto
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
operator= (aged_ordered_container const& other) ->
aged_ordered_container&
{
@@ -1433,9 +1433,9 @@ operator= (aged_ordered_container const& other) ->
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
class Clock, class Compare, class Allocator>
auto
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
operator= (aged_ordered_container&& other) ->
aged_ordered_container&
{
@@ -1447,9 +1447,9 @@ operator= (aged_ordered_container&& other) ->
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
class Clock, class Compare, class Allocator>
auto
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
operator= (std::initializer_list <value_type> init) ->
aged_ordered_container&
{
@@ -1461,10 +1461,10 @@ operator= (std::initializer_list <value_type> init) ->
//------------------------------------------------------------------------------
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
class Clock, class Compare, class Allocator>
template <class K, bool maybe_multi, bool maybe_map, class>
typename std::conditional <IsMap, T, void*>::type&
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
at (K const& k)
{
auto const iter (m_cont.find (k,
@@ -1475,10 +1475,10 @@ at (K const& k)
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
class Clock, class Compare, class Allocator>
template <class K, bool maybe_multi, bool maybe_map, class>
typename std::conditional <IsMap, T, void*>::type const&
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
at (K const& k) const
{
auto const iter (m_cont.find (k,
@@ -1489,10 +1489,10 @@ at (K const& k) const
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
class Clock, class Compare, class Allocator>
template <bool maybe_multi, bool maybe_map, class>
typename std::conditional <IsMap, T, void*>::type&
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
operator[] (Key const& key)
{
typename cont_type::insert_commit_data d;
@@ -1511,10 +1511,10 @@ operator[] (Key const& key)
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
class Clock, class Compare, class Allocator>
template <bool maybe_multi, bool maybe_map, class>
typename std::conditional <IsMap, T, void*>::type&
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
operator[] (Key&& key)
{
typename cont_type::insert_commit_data d;
@@ -1536,9 +1536,9 @@ operator[] (Key&& key)
//------------------------------------------------------------------------------
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
class Clock, class Compare, class Allocator>
void
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
clear()
{
for (auto iter (chronological.list.begin());
@@ -1550,10 +1550,10 @@ clear()
// map, set
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
class Clock, class Compare, class Allocator>
template <bool maybe_multi>
auto
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
insert (value_type const& value) ->
typename std::enable_if <! maybe_multi,
std::pair <iterator, bool>>::type
@@ -1573,10 +1573,10 @@ insert (value_type const& value) ->
// multimap, multiset
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
class Clock, class Compare, class Allocator>
template <bool maybe_multi>
auto
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
insert (value_type const& value) ->
typename std::enable_if <maybe_multi,
iterator>::type
@@ -1591,10 +1591,10 @@ insert (value_type const& value) ->
// set
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
class Clock, class Compare, class Allocator>
template <bool maybe_multi, bool maybe_map>
auto
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
insert (value_type&& value) ->
typename std::enable_if <! maybe_multi && ! maybe_map,
std::pair <iterator, bool>>::type
@@ -1614,10 +1614,10 @@ insert (value_type&& value) ->
// multiset
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
class Clock, class Compare, class Allocator>
template <bool maybe_multi, bool maybe_map>
auto
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
insert (value_type&& value) ->
typename std::enable_if <maybe_multi && ! maybe_map,
iterator>::type
@@ -1634,10 +1634,10 @@ insert (value_type&& value) ->
// map, set
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
class Clock, class Compare, class Allocator>
template <bool maybe_multi>
auto
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
insert (const_iterator hint, value_type const& value) ->
typename std::enable_if <! maybe_multi,
iterator>::type
@@ -1657,10 +1657,10 @@ insert (const_iterator hint, value_type const& value) ->
// map, set
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
class Clock, class Compare, class Allocator>
template <bool maybe_multi>
auto
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
insert (const_iterator hint, value_type&& value) ->
typename std::enable_if <! maybe_multi,
iterator>::type
@@ -1680,10 +1680,10 @@ insert (const_iterator hint, value_type&& value) ->
// map, set
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
class Clock, class Compare, class Allocator>
template <bool maybe_multi, class... Args>
auto
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
emplace (Args&&... args) ->
typename std::enable_if <! maybe_multi,
std::pair <iterator, bool>>::type
@@ -1707,10 +1707,10 @@ emplace (Args&&... args) ->
// multiset, multimap
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
class Clock, class Compare, class Allocator>
template <bool maybe_multi, class... Args>
auto
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
emplace (Args&&... args) ->
typename std::enable_if <maybe_multi,
iterator>::type
@@ -1726,10 +1726,10 @@ emplace (Args&&... args) ->
// map, set
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
class Clock, class Compare, class Allocator>
template <bool maybe_multi, class... Args>
auto
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
emplace_hint (const_iterator hint, Args&&... args) ->
typename std::enable_if <! maybe_multi,
std::pair <iterator, bool>>::type
@@ -1752,10 +1752,10 @@ emplace_hint (const_iterator hint, Args&&... args) ->
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
class Clock, class Compare, class Allocator>
template <bool is_const, class Iterator, class Base, class>
detail::aged_container_iterator <false, Iterator, Base>
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
erase (detail::aged_container_iterator <is_const, Iterator, Base> pos)
{
unlink_and_delete_element(&*((pos++).iterator()));
@@ -1764,10 +1764,10 @@ erase (detail::aged_container_iterator <is_const, Iterator, Base> pos)
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
class Clock, class Compare, class Allocator>
template <bool is_const, class Iterator, class Base, class>
detail::aged_container_iterator <false, Iterator, Base>
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
erase (detail::aged_container_iterator <is_const, Iterator, Base> first,
detail::aged_container_iterator <is_const, Iterator, Base> last)
{
@@ -1779,10 +1779,10 @@ erase (detail::aged_container_iterator <is_const, Iterator, Base> first,
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
class Clock, class Compare, class Allocator>
template <class K>
auto
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
erase (K const& k) ->
size_type
{
@@ -1805,9 +1805,9 @@ erase (K const& k) ->
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
class Clock, class Compare, class Allocator>
void
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
swap (aged_ordered_container& other) noexcept
{
swap_data (other);
@@ -1818,10 +1818,10 @@ swap (aged_ordered_container& other) noexcept
//------------------------------------------------------------------------------
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
class Clock, class Compare, class Allocator>
template <class K>
auto
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
touch (K const& k) ->
size_type
{
@@ -1839,19 +1839,19 @@ touch (K const& k) ->
//------------------------------------------------------------------------------
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
class Clock, class Compare, class Allocator>
template <bool OtherIsMulti, bool OtherIsMap,
class OtherT, class OtherDuration, class OtherAllocator>
bool
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
operator== (
aged_ordered_container <OtherIsMulti, OtherIsMap,
Key, OtherT, OtherDuration, Compare,
OtherAllocator> const& other) const
{
typedef aged_ordered_container <OtherIsMulti, OtherIsMap,
using Other = aged_ordered_container <OtherIsMulti, OtherIsMap,
Key, OtherT, OtherDuration, Compare,
OtherAllocator> Other;
OtherAllocator>;
if (size() != other.size())
return false;
std::equal_to <void> eq;
@@ -1866,10 +1866,10 @@ operator== (
//------------------------------------------------------------------------------
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
class Clock, class Compare, class Allocator>
template <bool is_const, class Iterator, class Base, class>
void
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
touch (detail::aged_container_iterator <
is_const, Iterator, Base> pos,
typename clock_type::time_point const& now)
@@ -1881,10 +1881,10 @@ touch (detail::aged_container_iterator <
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
class Clock, class Compare, class Allocator>
template <bool maybe_propagate>
typename std::enable_if <maybe_propagate>::type
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
swap_data (aged_ordered_container& other) noexcept
{
std::swap (m_config.key_compare(), other.m_config.key_compare());
@@ -1893,10 +1893,10 @@ swap_data (aged_ordered_container& other) noexcept
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
class Clock, class Compare, class Allocator>
template <bool maybe_propagate>
typename std::enable_if <! maybe_propagate>::type
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
swap_data (aged_ordered_container& other) noexcept
{
std::swap (m_config.key_compare(), other.m_config.key_compare());
@@ -1908,9 +1908,9 @@ swap_data (aged_ordered_container& other) noexcept
//------------------------------------------------------------------------------
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
class Clock, class Compare, class Allocator>
struct is_aged_container <detail::aged_ordered_container <
IsMulti, IsMap, Key, T, Duration, Compare, Allocator>>
IsMulti, IsMap, Key, T, Clock, Compare, Allocator>>
: std::true_type
{
};
@@ -1918,22 +1918,22 @@ struct is_aged_container <detail::aged_ordered_container <
// Free functions
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
class Clock, class Compare, class Allocator>
void swap (
detail::aged_ordered_container <IsMulti, IsMap,
Key, T, Duration, Compare, Allocator>& lhs,
Key, T, Clock, Compare, Allocator>& lhs,
detail::aged_ordered_container <IsMulti, IsMap,
Key, T, Duration, Compare, Allocator>& rhs) noexcept
Key, T, Clock, Compare, Allocator>& rhs) noexcept
{
lhs.swap (rhs);
}
/** Expire aged container items past the specified age. */
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator,
class Clock, class Compare, class Allocator,
class Rep, class Period>
std::size_t expire (detail::aged_ordered_container <
IsMulti, IsMap, Key, T, Duration, Compare, Allocator>& c,
IsMulti, IsMap, Key, T, Clock, Compare, Allocator>& c,
std::chrono::duration <Rep, Period> const& age)
{
std::size_t n (0);

View File

@@ -17,20 +17,16 @@
*/
//==============================================================================
#ifndef BEAST_CONTAINER_AGED_UNORDERED_CONTAINER_H_INCLUDED
#define BEAST_CONTAINER_AGED_UNORDERED_CONTAINER_H_INCLUDED
#ifndef BEAST_CONTAINER_DETAIL_AGED_UNORDERED_CONTAINER_H_INCLUDED
#define BEAST_CONTAINER_DETAIL_AGED_UNORDERED_CONTAINER_H_INCLUDED
#include <beast/container/detail/aged_container_iterator.h>
#include <beast/container/detail/aged_associative_container.h>
#include <beast/container/aged_container.h>
#include <beast/chrono/abstract_clock.h>
#include <beast/utility/empty_base_optimization.h>
#include <boost/intrusive/list.hpp>
#include <boost/intrusive/unordered_set.hpp>
#include <beast/cxx14/algorithm.h> // <algorithm>
#include <functional>
#include <initializer_list>
@@ -80,7 +76,7 @@ template <
bool IsMap,
class Key,
class T,
class Duration = std::chrono::seconds,
class Clock = std::chrono::steady_clock,
class Hash = std::hash <Key>,
class KeyEqual = std::equal_to <Key>,
class Allocator = std::allocator <
@@ -91,24 +87,20 @@ template <
class aged_unordered_container
{
public:
typedef abstract_clock <Duration> clock_type;
typedef typename clock_type::time_point time_point;
typedef typename clock_type::duration duration;
typedef Key key_type;
typedef T mapped_type;
typedef typename std::conditional <IsMap,
std::pair <Key const, T>,
Key>::type value_type;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
using clock_type = abstract_clock<Clock>;
using time_point = typename clock_type::time_point;
using duration = typename clock_type::duration;
using key_type = Key;
using mapped_type = T;
using value_type = typename std::conditional <IsMap,
std::pair <Key const, T>, Key>::type;
using size_type = std::size_t;
using difference_type = std::ptrdiff_t;
// Introspection (for unit tests)
typedef std::true_type is_unordered;
typedef std::integral_constant <bool, IsMulti> is_multi;
typedef std::integral_constant <bool, IsMap> is_map;
// VFALCO TODO How can we reorder the declarations to keep
// all the public things together contiguously?
using is_unordered = std::true_type;
using is_multi = std::integral_constant <bool, IsMulti>;
using is_map = std::integral_constant <bool, IsMap>;
private:
static Key const& extract (value_type const& value)
@@ -131,8 +123,8 @@ private:
// need to see the container declaration.
struct stashed
{
typedef typename aged_unordered_container::value_type value_type;
typedef typename aged_unordered_container::time_point time_point;
using value_type = typename aged_unordered_container::value_type;
using time_point = typename aged_unordered_container::time_point;
};
element (
@@ -256,11 +248,10 @@ private:
}
};
typedef typename boost::intrusive::make_list <element,
boost::intrusive::constant_time_size <false>
>::type list_type;
using list_type = typename boost::intrusive::make_list <element,
boost::intrusive::constant_time_size <false>>::type ;
typedef typename std::conditional <
using cont_type = typename std::conditional <
IsMulti,
typename boost::intrusive::make_unordered_multiset <element,
boost::intrusive::constant_time_size <true>,
@@ -274,18 +265,18 @@ private:
boost::intrusive::equal <KeyValueEqual>,
boost::intrusive::cache_begin <true>
>::type
>::type cont_type;
>::type;
typedef typename cont_type::bucket_type bucket_type;
typedef typename cont_type::bucket_traits bucket_traits;
using bucket_type = typename cont_type::bucket_type;
using bucket_traits = typename cont_type::bucket_traits;
typedef typename std::allocator_traits <
Allocator>::template rebind_alloc <element> ElementAllocator;
using ElementAllocator = typename std::allocator_traits <
Allocator>::template rebind_alloc <element>;
using ElementAllocatorTraits = std::allocator_traits <ElementAllocator>;
typedef typename std::allocator_traits <
Allocator>::template rebind_alloc <element> BucketAllocator;
using BucketAllocator = typename std::allocator_traits <
Allocator>::template rebind_alloc <element>;
using BucketAllocatorTraits = std::allocator_traits <BucketAllocator>;
@@ -479,10 +470,10 @@ private:
class Buckets
{
public:
typedef std::vector <
using vec_type = std::vector<
bucket_type,
typename std::allocator_traits <Allocator>::
template rebind_alloc <bucket_type>> vec_type;
template rebind_alloc <bucket_type>>;
Buckets ()
: m_max_load_factor (1.f)
@@ -615,27 +606,27 @@ private:
}
public:
typedef Hash hasher;
typedef KeyEqual key_equal;
typedef Allocator allocator_type;
typedef value_type& reference;
typedef value_type const& const_reference;
typedef typename std::allocator_traits <
Allocator>::pointer pointer;
typedef typename std::allocator_traits <
Allocator>::const_pointer const_pointer;
using hasher = Hash;
using key_equal = KeyEqual;
using allocator_type = Allocator;
using reference = value_type&;
using const_reference = value_type const&;
using pointer = typename std::allocator_traits <
Allocator>::pointer;
using const_pointer = typename std::allocator_traits <
Allocator>::const_pointer;
// A set (that is, !IsMap) iterator is aways const because the elements
// of a set are immutable.
typedef detail::aged_container_iterator <!IsMap,
typename cont_type::iterator> iterator;
typedef detail::aged_container_iterator <true,
typename cont_type::iterator> const_iterator;
// A set iterator (IsMap==false) is always const
// because the elements of a set are immutable.
using iterator= detail::aged_container_iterator <!IsMap,
typename cont_type::iterator>;
using const_iterator = detail::aged_container_iterator <true,
typename cont_type::iterator>;
typedef detail::aged_container_iterator <!IsMap,
typename cont_type::local_iterator> local_iterator;
typedef detail::aged_container_iterator <true,
typename cont_type::local_iterator> const_local_iterator;
using local_iterator = detail::aged_container_iterator <!IsMap,
typename cont_type::local_iterator>;
using const_local_iterator = detail::aged_container_iterator <true,
typename cont_type::local_iterator>;
//--------------------------------------------------------------------------
//
@@ -649,16 +640,16 @@ public:
class chronological_t
{
public:
// A set (that is, !IsMap) iterator is aways const because the elements
// of a set are immutable.
typedef detail::aged_container_iterator <!IsMap,
typename list_type::iterator> iterator;
typedef detail::aged_container_iterator <true,
typename list_type::iterator> const_iterator;
typedef detail::aged_container_iterator <!IsMap,
typename list_type::reverse_iterator> reverse_iterator;
typedef detail::aged_container_iterator <true,
typename list_type::reverse_iterator> const_reverse_iterator;
// A set iterator (IsMap==false) is always const
// because the elements of a set are immutable.
using iterator = detail::aged_container_iterator <
! IsMap, typename list_type::iterator>;
using const_iterator = detail::aged_container_iterator <
true, typename list_type::iterator>;
using reverse_iterator = detail::aged_container_iterator <
! IsMap, typename list_type::reverse_iterator>;
using const_reverse_iterator = detail::aged_container_iterator <
true, typename list_type::reverse_iterator>;
iterator begin ()
{
@@ -756,6 +747,8 @@ public:
//
//--------------------------------------------------------------------------
aged_unordered_container() = delete;
explicit aged_unordered_container (clock_type& clock);
aged_unordered_container (clock_type& clock, Hash const& hash);
@@ -1504,8 +1497,8 @@ private:
//------------------------------------------------------------------------------
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
class Clock, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
aged_unordered_container (
clock_type& clock)
@@ -1517,8 +1510,8 @@ aged_unordered_container (
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
class Clock, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
aged_unordered_container (
clock_type& clock,
@@ -1531,8 +1524,8 @@ aged_unordered_container (
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
class Clock, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
aged_unordered_container (
clock_type& clock,
@@ -1545,8 +1538,8 @@ aged_unordered_container (
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
class Clock, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
aged_unordered_container (
clock_type& clock,
@@ -1560,8 +1553,8 @@ aged_unordered_container (
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
class Clock, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
aged_unordered_container (
clock_type& clock,
@@ -1575,8 +1568,8 @@ aged_unordered_container (
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
class Clock, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
aged_unordered_container (
clock_type& clock,
@@ -1591,8 +1584,8 @@ aged_unordered_container (
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
class Clock, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
aged_unordered_container (
clock_type& clock,
@@ -1607,8 +1600,8 @@ aged_unordered_container (
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
class Clock, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
aged_unordered_container (
clock_type& clock,
@@ -1624,9 +1617,9 @@ aged_unordered_container (
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
template <class InputIt>
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
aged_unordered_container (InputIt first, InputIt last,
clock_type& clock)
@@ -1639,9 +1632,9 @@ aged_unordered_container (InputIt first, InputIt last,
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
template <class InputIt>
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
aged_unordered_container (InputIt first, InputIt last,
clock_type& clock,
@@ -1655,9 +1648,9 @@ aged_unordered_container (InputIt first, InputIt last,
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
template <class InputIt>
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
aged_unordered_container (InputIt first, InputIt last,
clock_type& clock,
@@ -1671,9 +1664,9 @@ aged_unordered_container (InputIt first, InputIt last,
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
template <class InputIt>
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
aged_unordered_container (InputIt first, InputIt last,
clock_type& clock,
@@ -1688,9 +1681,9 @@ aged_unordered_container (InputIt first, InputIt last,
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
template <class InputIt>
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
aged_unordered_container (InputIt first, InputIt last,
clock_type& clock,
@@ -1705,9 +1698,9 @@ aged_unordered_container (InputIt first, InputIt last,
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
template <class InputIt>
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
aged_unordered_container (InputIt first, InputIt last,
clock_type& clock,
@@ -1723,9 +1716,9 @@ aged_unordered_container (InputIt first, InputIt last,
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
template <class InputIt>
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
aged_unordered_container (InputIt first, InputIt last,
clock_type& clock,
@@ -1741,9 +1734,9 @@ aged_unordered_container (InputIt first, InputIt last,
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
template <class InputIt>
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
aged_unordered_container (InputIt first, InputIt last,
clock_type& clock,
@@ -1760,8 +1753,8 @@ aged_unordered_container (InputIt first, InputIt last,
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
class Clock, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
aged_unordered_container (aged_unordered_container const& other)
: m_config (other.m_config)
@@ -1774,8 +1767,8 @@ aged_unordered_container (aged_unordered_container const& other)
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
class Clock, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
aged_unordered_container (aged_unordered_container const& other,
Allocator const& alloc)
@@ -1789,8 +1782,8 @@ aged_unordered_container (aged_unordered_container const& other,
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
class Clock, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
aged_unordered_container (aged_unordered_container&& other)
: m_config (std::move (other.m_config))
@@ -1801,8 +1794,8 @@ aged_unordered_container (aged_unordered_container&& other)
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
class Clock, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
aged_unordered_container (aged_unordered_container&& other,
Allocator const& alloc)
@@ -1817,8 +1810,8 @@ aged_unordered_container (aged_unordered_container&& other,
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
class Clock, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
aged_unordered_container (std::initializer_list <value_type> init,
clock_type& clock)
@@ -1831,8 +1824,8 @@ aged_unordered_container (std::initializer_list <value_type> init,
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
class Clock, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
aged_unordered_container (std::initializer_list <value_type> init,
clock_type& clock,
@@ -1846,8 +1839,8 @@ aged_unordered_container (std::initializer_list <value_type> init,
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
class Clock, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
aged_unordered_container (std::initializer_list <value_type> init,
clock_type& clock,
@@ -1861,8 +1854,8 @@ aged_unordered_container (std::initializer_list <value_type> init,
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
class Clock, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
aged_unordered_container (std::initializer_list <value_type> init,
clock_type& clock,
@@ -1877,8 +1870,8 @@ aged_unordered_container (std::initializer_list <value_type> init,
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
class Clock, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
aged_unordered_container (std::initializer_list <value_type> init,
clock_type& clock,
@@ -1893,8 +1886,8 @@ aged_unordered_container (std::initializer_list <value_type> init,
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
class Clock, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
aged_unordered_container (std::initializer_list <value_type> init,
clock_type& clock,
@@ -1910,8 +1903,8 @@ aged_unordered_container (std::initializer_list <value_type> init,
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
class Clock, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
aged_unordered_container (std::initializer_list <value_type> init,
clock_type& clock,
@@ -1927,8 +1920,8 @@ aged_unordered_container (std::initializer_list <value_type> init,
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
class Clock, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
aged_unordered_container (std::initializer_list <value_type> init,
clock_type& clock,
@@ -1945,8 +1938,8 @@ aged_unordered_container (std::initializer_list <value_type> init,
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
class Clock, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
~aged_unordered_container()
{
@@ -1954,9 +1947,9 @@ aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
auto
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
operator= (aged_unordered_container const& other)
-> aged_unordered_container&
@@ -1974,9 +1967,9 @@ operator= (aged_unordered_container const& other)
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
auto
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
operator= (aged_unordered_container&& other) ->
aged_unordered_container&
@@ -1992,9 +1985,9 @@ operator= (aged_unordered_container&& other) ->
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
auto
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
operator= (std::initializer_list <value_type> init) ->
aged_unordered_container&
@@ -2007,10 +2000,10 @@ operator= (std::initializer_list <value_type> init) ->
//------------------------------------------------------------------------------
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
template <class K, bool maybe_multi, bool maybe_map, class>
typename std::conditional <IsMap, T, void*>::type&
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
at (K const& k)
{
@@ -2023,10 +2016,10 @@ at (K const& k)
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
template <class K, bool maybe_multi, bool maybe_map, class>
typename std::conditional <IsMap, T, void*>::type const&
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
at (K const& k) const
{
@@ -2039,10 +2032,10 @@ at (K const& k) const
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
template <bool maybe_multi, bool maybe_map, class>
typename std::conditional <IsMap, T, void*>::type&
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
operator[] (Key const& key)
{
@@ -2065,10 +2058,10 @@ operator[] (Key const& key)
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
template <bool maybe_multi, bool maybe_map, class>
typename std::conditional <IsMap, T, void*>::type&
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
operator[] (Key&& key)
{
@@ -2093,9 +2086,9 @@ operator[] (Key&& key)
//------------------------------------------------------------------------------
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
void
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
clear()
{
@@ -2109,10 +2102,10 @@ clear()
// map, set
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
template <bool maybe_multi>
auto
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
insert (value_type const& value) ->
typename std::enable_if <! maybe_multi,
@@ -2135,10 +2128,10 @@ insert (value_type const& value) ->
// multimap, multiset
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
template <bool maybe_multi>
auto
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
insert (value_type const& value) ->
typename std::enable_if <maybe_multi,
@@ -2153,10 +2146,10 @@ insert (value_type const& value) ->
// map, set
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
template <bool maybe_multi, bool maybe_map>
auto
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
insert (value_type&& value) ->
typename std::enable_if <! maybe_multi && ! maybe_map,
@@ -2179,10 +2172,10 @@ insert (value_type&& value) ->
// multimap, multiset
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
template <bool maybe_multi, bool maybe_map>
auto
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
insert (value_type&& value) ->
typename std::enable_if <maybe_multi && ! maybe_map,
@@ -2198,10 +2191,10 @@ insert (value_type&& value) ->
#if 1 // Use insert() instead of insert_check() insert_commit()
// set, map
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
template <bool maybe_multi, class... Args>
auto
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
emplace (Args&&... args) ->
typename std::enable_if <! maybe_multi,
@@ -2223,10 +2216,10 @@ emplace (Args&&... args) ->
#else // As original, use insert_check() / insert_commit () pair.
// set, map
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
template <bool maybe_multi, class... Args>
auto
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
emplace (Args&&... args) ->
typename std::enable_if <! maybe_multi,
@@ -2254,10 +2247,10 @@ emplace (Args&&... args) ->
// multiset, multimap
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
template <bool maybe_multi, class... Args>
auto
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
emplace (Args&&... args) ->
typename std::enable_if <maybe_multi,
@@ -2273,10 +2266,10 @@ emplace (Args&&... args) ->
// set, map
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
template <bool maybe_multi, class... Args>
auto
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
emplace_hint (const_iterator /*hint*/, Args&&... args) ->
typename std::enable_if <! maybe_multi,
@@ -2302,10 +2295,10 @@ emplace_hint (const_iterator /*hint*/, Args&&... args) ->
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
template <bool is_const, class Iterator, class Base>
detail::aged_container_iterator <false, Iterator, Base>
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
erase (detail::aged_container_iterator <
is_const, Iterator, Base> pos)
@@ -2316,10 +2309,10 @@ erase (detail::aged_container_iterator <
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
template <bool is_const, class Iterator, class Base>
detail::aged_container_iterator <false, Iterator, Base>
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
erase (detail::aged_container_iterator <
is_const, Iterator, Base> first,
@@ -2334,10 +2327,10 @@ erase (detail::aged_container_iterator <
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
template <class K>
auto
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
erase (K const& k) ->
size_type
@@ -2361,9 +2354,9 @@ erase (K const& k) ->
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
void
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
swap (aged_unordered_container& other) noexcept
{
@@ -2373,10 +2366,10 @@ swap (aged_unordered_container& other) noexcept
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
template <class K>
auto
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
touch (K const& k) ->
size_type
@@ -2393,7 +2386,7 @@ touch (K const& k) ->
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
template <
bool OtherIsMap,
class OtherKey,
@@ -2405,7 +2398,7 @@ template <
>
typename std::enable_if <! maybe_multi, bool>::type
aged_unordered_container <
IsMulti, IsMap, Key, T, Duration, Hash, KeyEqual, Allocator>::
IsMulti, IsMap, Key, T, Clock, Hash, KeyEqual, Allocator>::
operator== (
aged_unordered_container <false, OtherIsMap,
OtherKey, OtherT, OtherDuration, OtherHash, KeyEqual,
@@ -2424,7 +2417,7 @@ operator== (
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
template <
bool OtherIsMap,
class OtherKey,
@@ -2436,7 +2429,7 @@ template <
>
typename std::enable_if <maybe_multi, bool>::type
aged_unordered_container <
IsMulti, IsMap, Key, T, Duration, Hash, KeyEqual, Allocator>::
IsMulti, IsMap, Key, T, Clock, Hash, KeyEqual, Allocator>::
operator== (
aged_unordered_container <true, OtherIsMap,
OtherKey, OtherT, OtherDuration, OtherHash, KeyEqual,
@@ -2444,7 +2437,7 @@ operator== (
{
if (size() != other.size())
return false;
typedef std::pair <const_iterator, const_iterator> EqRng;
using EqRng = std::pair <const_iterator, const_iterator>;
for (auto iter (cbegin()), last (cend()); iter != last;)
{
auto const& k (extract (*iter));
@@ -2469,10 +2462,10 @@ operator== (
// map, set
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
template <bool maybe_multi>
auto
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
insert_unchecked (value_type const& value) ->
typename std::enable_if <! maybe_multi,
@@ -2494,10 +2487,10 @@ insert_unchecked (value_type const& value) ->
// multimap, multiset
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
template <bool maybe_multi>
auto
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
insert_unchecked (value_type const& value) ->
typename std::enable_if <maybe_multi,
@@ -2516,32 +2509,32 @@ insert_unchecked (value_type const& value) ->
//------------------------------------------------------------------------------
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
struct is_aged_container <detail::aged_unordered_container <
IsMulti, IsMap, Key, T, Duration, Hash, KeyEqual, Allocator>>
IsMulti, IsMap, Key, T, Clock, Hash, KeyEqual, Allocator>>
: std::true_type
{
};
// Free functions
template <bool IsMulti, bool IsMap, class Key, class T, class Duration,
template <bool IsMulti, bool IsMap, class Key, class T, class Clock,
class Hash, class KeyEqual, class Allocator>
void swap (
detail::aged_unordered_container <IsMulti, IsMap,
Key, T, Duration, Hash, KeyEqual, Allocator>& lhs,
Key, T, Clock, Hash, KeyEqual, Allocator>& lhs,
detail::aged_unordered_container <IsMulti, IsMap,
Key, T, Duration, Hash, KeyEqual, Allocator>& rhs) noexcept
Key, T, Clock, Hash, KeyEqual, Allocator>& rhs) noexcept
{
lhs.swap (rhs);
}
/** Expire aged container items past the specified age. */
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator,
class Clock, class Hash, class KeyEqual, class Allocator,
class Rep, class Period>
std::size_t expire (detail::aged_unordered_container <
IsMulti, IsMap, Key, T, Duration, Hash, KeyEqual, Allocator>& c,
IsMulti, IsMap, Key, T, Clock, Hash, KeyEqual, Allocator>& c,
std::chrono::duration <Rep, Period> const& age) noexcept
{
std::size_t n (0);

View File

@@ -302,7 +302,7 @@ public:
>
using Cont = detail::aged_ordered_container <
Base::is_multi::value, Base::is_map::value, typename Base::Key,
typename Base::T, typename Base::Dur, Compare, Allocator>;
typename Base::T, typename Base::Clock, Compare, Allocator>;
};
// unordered
@@ -318,7 +318,7 @@ public:
>
using Cont = detail::aged_unordered_container <
Base::is_multi::value, Base::is_map::value,
typename Base::Key, typename Base::T, typename Base::Dur,
typename Base::Key, typename Base::T, typename Base::Clock,
Hash, KeyEqual, Allocator>;
};
@@ -327,8 +327,8 @@ public:
struct TestTraitsBase
{
typedef std::string Key;
typedef std::chrono::seconds Dur;
typedef manual_clock <Dur> Clock;
typedef std::chrono::steady_clock Clock;
typedef manual_clock<Clock> ManualClock;
};
template <bool IsUnordered, bool IsMulti, bool IsMap>
@@ -387,10 +387,10 @@ public:
template <class Cont>
static
std::list <typename Cont::value_type>
std::vector <typename Cont::value_type>
make_list (Cont const& c)
{
return std::list <typename Cont::value_type> (
return std::vector <typename Cont::value_type> (
c.begin(), c.end());
}
@@ -744,12 +744,12 @@ testConstructEmpty ()
typedef typename Traits::Value Value;
typedef typename Traits::Key Key;
typedef typename Traits::T T;
typedef typename Traits::Dur Dur;
typedef typename Traits::Clock Clock;
typedef typename Traits::Comp Comp;
typedef typename Traits::Alloc Alloc;
typedef typename Traits::MyComp MyComp;
typedef typename Traits::MyAlloc MyAlloc;
typename Traits::Clock clock;
typename Traits::ManualClock clock;
//testcase (Traits::name() + " empty");
testcase ("empty");
@@ -789,14 +789,14 @@ testConstructEmpty ()
typedef typename Traits::Value Value;
typedef typename Traits::Key Key;
typedef typename Traits::T T;
typedef typename Traits::Dur Dur;
typedef typename Traits::Clock Clock;
typedef typename Traits::Hash Hash;
typedef typename Traits::Equal Equal;
typedef typename Traits::Alloc Alloc;
typedef typename Traits::MyHash MyHash;
typedef typename Traits::MyEqual MyEqual;
typedef typename Traits::MyAlloc MyAlloc;
typename Traits::Clock clock;
typename Traits::ManualClock clock;
//testcase (Traits::name() + " empty");
testcase ("empty");
@@ -859,12 +859,12 @@ testConstructRange ()
typedef typename Traits::Value Value;
typedef typename Traits::Key Key;
typedef typename Traits::T T;
typedef typename Traits::Dur Dur;
typedef typename Traits::Clock Clock;
typedef typename Traits::Comp Comp;
typedef typename Traits::Alloc Alloc;
typedef typename Traits::MyComp MyComp;
typedef typename Traits::MyAlloc MyAlloc;
typename Traits::Clock clock;
typename Traits::ManualClock clock;
auto const v (Traits::values());
//testcase (Traits::name() + " range");
@@ -922,14 +922,14 @@ testConstructRange ()
typedef typename Traits::Value Value;
typedef typename Traits::Key Key;
typedef typename Traits::T T;
typedef typename Traits::Dur Dur;
typedef typename Traits::Clock Clock;
typedef typename Traits::Hash Hash;
typedef typename Traits::Equal Equal;
typedef typename Traits::Alloc Alloc;
typedef typename Traits::MyHash MyHash;
typedef typename Traits::MyEqual MyEqual;
typedef typename Traits::MyAlloc MyAlloc;
typename Traits::Clock clock;
typename Traits::ManualClock clock;
auto const v (Traits::values());
//testcase (Traits::name() + " range");
@@ -1002,12 +1002,12 @@ testConstructInitList ()
typedef typename Traits::Value Value;
typedef typename Traits::Key Key;
typedef typename Traits::T T;
typedef typename Traits::Dur Dur;
typedef typename Traits::Clock Clock;
typedef typename Traits::Comp Comp;
typedef typename Traits::Alloc Alloc;
typedef typename Traits::MyComp MyComp;
typedef typename Traits::MyAlloc MyAlloc;
typename Traits::Clock clock;
typename Traits::ManualClock clock;
//testcase (Traits::name() + " init-list");
testcase ("init-list");
@@ -1027,14 +1027,14 @@ testConstructInitList ()
typedef typename Traits::Value Value;
typedef typename Traits::Key Key;
typedef typename Traits::T T;
typedef typename Traits::Dur Dur;
typedef typename Traits::Clock Clock;
typedef typename Traits::Hash Hash;
typedef typename Traits::Equal Equal;
typedef typename Traits::Alloc Alloc;
typedef typename Traits::MyHash MyHash;
typedef typename Traits::MyEqual MyEqual;
typedef typename Traits::MyAlloc MyAlloc;
typename Traits::Clock clock;
typename Traits::ManualClock clock;
//testcase (Traits::name() + " init-list");
testcase ("init-list");
@@ -1057,7 +1057,7 @@ testCopyMove ()
typedef TestTraits <IsUnordered, IsMulti, IsMap> Traits;
typedef typename Traits::Value Value;
typedef typename Traits::Alloc Alloc;
typename Traits::Clock clock;
typename Traits::ManualClock clock;
auto const v (Traits::values());
//testcase (Traits::name() + " copy/move");
@@ -1139,7 +1139,7 @@ testIterator()
typedef TestTraits <IsUnordered, IsMulti, IsMap> Traits;
typedef typename Traits::Value Value;
typedef typename Traits::Alloc Alloc;
typename Traits::Clock clock;
typename Traits::ManualClock clock;
auto const v (Traits::values());
//testcase (Traits::name() + " iterators");
@@ -1202,7 +1202,7 @@ testReverseIterator()
typedef TestTraits <IsUnordered, IsMulti, IsMap> Traits;
typedef typename Traits::Value Value;
typedef typename Traits::Alloc Alloc;
typename Traits::Clock clock;
typename Traits::ManualClock clock;
auto const v (Traits::values());
//testcase (Traits::name() + " reverse_iterators");
@@ -1357,7 +1357,7 @@ aged_associative_container_test_base::
testModifiers()
{
typedef TestTraits <IsUnordered, IsMulti, IsMap> Traits;
typename Traits::Clock clock;
typename Traits::ManualClock clock;
auto const v (Traits::values());
auto const l (make_list (v));
@@ -1418,7 +1418,7 @@ testChronological ()
{
typedef TestTraits <IsUnordered, IsMulti, IsMap> Traits;
typedef typename Traits::Value Value;
typename Traits::Clock clock;
typename Traits::ManualClock clock;
auto const v (Traits::values());
//testcase (Traits::name() + " chronological");
@@ -1484,7 +1484,7 @@ aged_associative_container_test_base::
testArrayCreate()
{
typedef TestTraits <IsUnordered, IsMulti, IsMap> Traits;
typename Traits::Clock clock;
typename Traits::ManualClock clock;
auto v (Traits::values());
//testcase (Traits::name() + " array create");
@@ -1522,8 +1522,9 @@ reverseFillAgedContainer (Container& c, Values const& values)
c.clear();
// c.clock() returns an abstract_clock, so dynamic_cast to manual_clock.
typedef TestTraitsBase::Clock Clock;
Clock& clk (dynamic_cast <Clock&> (c.clock ()));
// VFALCO NOTE This is sketchy
typedef TestTraitsBase::ManualClock ManualClock;
ManualClock& clk (dynamic_cast <ManualClock&> (c.clock()));
clk.set (0);
Values rev (values);
@@ -1626,8 +1627,8 @@ testElementErase ()
testcase ("element erase");
// Make and fill the container
typename Traits::Clock ck;
typename Traits::template Cont <> c {ck};
typename Traits::ManualClock clock;
typename Traits::template Cont <> c {clock};
reverseFillAgedContainer (c, Traits::values());
{
@@ -1756,8 +1757,8 @@ testRangeErase ()
testcase ("range erase");
// Make and fill the container
typename Traits::Clock ck;
typename Traits::template Cont <> c {ck};
typename Traits::ManualClock clock;
typename Traits::template Cont <> c {clock};
reverseFillAgedContainer (c, Traits::values());
// Not bothering to test range erase with reverse iterators.
@@ -1785,7 +1786,7 @@ testCompare ()
{
typedef TestTraits <IsUnordered, IsMulti, IsMap> Traits;
typedef typename Traits::Value Value;
typename Traits::Clock clock;
typename Traits::ManualClock clock;
auto const v (Traits::values());
//testcase (Traits::name() + " array create");
@@ -1819,7 +1820,7 @@ aged_associative_container_test_base::
testObservers()
{
typedef TestTraits <IsUnordered, IsMulti, IsMap> Traits;
typename Traits::Clock clock;
typename Traits::ManualClock clock;
//testcase (Traits::name() + " observers");
testcase ("observers");
@@ -1838,7 +1839,7 @@ aged_associative_container_test_base::
testObservers()
{
typedef TestTraits <IsUnordered, IsMulti, IsMap> Traits;
typename Traits::Clock clock;
typename Traits::ManualClock clock;
//testcase (Traits::name() + " observers");
testcase ("observers");

View File

@@ -1,320 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
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.
*/
//==============================================================================
#include <beast/unit_test/suite.h>
#include <beast/container/buffer_view.h>
#include <beast/cxx14/algorithm.h> // <algorithm>
namespace beast {
class buffer_view_test : public unit_test::suite
{
public:
// Returns `true` if the iterator distance matches the size
template <class FwdIt, class Size>
static bool eq_dist (FwdIt first, FwdIt last, Size size)
{
auto const dist (std::distance (first, last));
static_assert (std::is_signed <decltype (dist)>::value,
"dist must be signed");
if (dist < 0)
return false;
return static_cast <Size> (dist) == size;
}
// Check the contents of a buffer_view against the container
template <class C, class T>
void check (C const& c, buffer_view <T> v)
{
expect (! v.empty() || c.empty());
expect (v.size() == c.size());
expect (v.max_size() == v.size());
expect (v.capacity() == v.size());
expect (eq_dist (v.begin(), v.end(), v.size()));
expect (eq_dist (v.cbegin(), v.cend(), v.size()));
expect (eq_dist (v.rbegin(), v.rend(), v.size()));
expect (eq_dist (v.crbegin(), v.crend(), v.size()));
expect (std::equal (
c.cbegin(), c.cend(), v.cbegin(), v.cend()));
expect (std::equal (
c.crbegin(), c.crend(), v.crbegin(), v.crend()));
if (v.size() == c.size())
{
if (! v.empty())
{
expect (v.front() == c.front());
expect (v.back() == c.back());
}
for (std::size_t i (0); i < v.size(); ++i)
expect (v[i] == c[i]);
}
}
//--------------------------------------------------------------------------
// Call at() with an invalid index
template <class V>
void checkBadIndex (V& v,
std::enable_if_t <
std::is_const <typename V::value_type>::value>* = 0)
{
try
{
v.at(0);
fail();
}
catch (std::out_of_range e)
{
pass();
}
catch (...)
{
fail();
}
}
// Call at() with an invalid index
template <class V>
void checkBadIndex (V& v,
std::enable_if_t <
! std::is_const <typename V::value_type>::value>* = 0)
{
try
{
v.at(0);
fail();
}
catch (std::out_of_range e)
{
pass();
}
catch (...)
{
fail();
}
try
{
v.at(0) = 1;
fail();
}
catch (std::out_of_range e)
{
pass();
}
catch (...)
{
fail();
}
}
// Checks invariants for an empty buffer_view
template <class V>
void checkEmpty (V& v)
{
expect (v.empty());
expect (v.size() == 0);
expect (v.max_size() == v.size());
expect (v.capacity() == v.size());
expect (v.begin() == v.end());
expect (v.cbegin() == v.cend());
expect (v.begin() == v.cend());
expect (v.rbegin() == v.rend());
expect (v.crbegin() == v.rend());
checkBadIndex (v);
}
// Test empty containers
void testEmpty()
{
testcase ("empty");
buffer_view <char> v1;
checkEmpty (v1);
buffer_view <char> v2;
swap (v1, v2);
checkEmpty (v1);
checkEmpty (v2);
buffer_view <char const> v3 (v2);
checkEmpty (v3);
}
//--------------------------------------------------------------------------
// Construct const views from a container
template <class C>
void testConstructConst (C const& c)
{
typedef buffer_view <std::add_const_t <
typename C::value_type>> V;
{
// construct from container
V v (c);
check (c, v);
// construct from buffer_view
V v2 (v);
check (c, v2);
}
if (! c.empty())
{
{
// construct from const pointer range
V v (&c.front(), &c.back()+1);
check (c, v);
// construct from pointer and size
V v2 (&c.front(), c.size());
check (v, v2);
}
{
// construct from non const pointer range
C cp (c);
V v (&cp.front(), &cp.back()+1);
check (cp, v);
// construct from pointer and size
V v2 (&cp.front(), cp.size());
check (v, v2);
// construct from data and size
V v3 (v2.data(), v2.size());
check (c, v3);
}
}
}
// Construct view from a container
template <class C>
void testConstruct (C const& c)
{
static_assert (! std::is_const <typename C::value_type>::value,
"Container value_type cannot be const");
testConstructConst (c);
typedef buffer_view <typename C::value_type> V;
C cp (c);
V v (cp);
check (cp, v);
std::reverse (v.begin(), v.end());
check (cp, v);
expect (std::equal (v.rbegin(), v.rend(),
c.begin(), c.end()));
}
void testConstruct()
{
testcase ("std::vector <char>");
testConstruct (
std::vector <char> ({'h', 'e', 'l', 'l', 'o'}));
testcase ("std::string <char>");
testConstruct (
std::basic_string <char> ("hello"));
}
//--------------------------------------------------------------------------
void testCoerce()
{
testcase ("coerce");
std::string const s ("hello");
const_buffer_view <unsigned char> v (s);
pass();
}
//--------------------------------------------------------------------------
void testAssign()
{
testcase ("testAssign");
std::vector <int> v1({1, 2, 3});
buffer_view<int> r1(v1);
std::vector <int> v2({4, 5, 6, 7});
buffer_view<int> r2(v2);
r1 = r2;
expect (std::equal (r1.begin(), r1.end(), v2.begin(), v2.end()));
}
//--------------------------------------------------------------------------
static_assert (std::is_constructible <buffer_view <int>,
std::vector <int>&>::value, "");
static_assert (!std::is_constructible <buffer_view <int>,
std::vector <int> const&>::value, "");
static_assert (std::is_constructible <buffer_view <int const>,
std::vector <int>&>::value, "");
static_assert (std::is_constructible <buffer_view <int const>,
std::vector <int> const&>::value, "");
static_assert (std::is_nothrow_default_constructible <
buffer_view <int>>::value, "");
static_assert (std::is_nothrow_destructible <
buffer_view <int>>::value, "");
static_assert (std::is_nothrow_copy_constructible <
buffer_view <int>>::value, "");
static_assert (std::is_nothrow_copy_assignable <
buffer_view<int>>::value, "");
static_assert (std::is_nothrow_move_constructible <
buffer_view <int>>::value, "");
static_assert (std::is_nothrow_move_assignable <
buffer_view <int>>::value, "");
void run()
{
testEmpty();
testConstruct();
testCoerce();
testAssign();
}
};
BEAST_DEFINE_TESTSUITE(buffer_view,container,beast);
}

View File

@@ -21,7 +21,6 @@
#include <BeastConfig.h>
#endif
#include <beast/crypto/impl/MurmurHash.cpp>
#include <beast/crypto/impl/Sha256.cpp>
#include <beast/crypto/tests/base64.test.cpp>

View File

@@ -1,84 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
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 BEAST_CRYPTO_MURMURHASH_H_INCLUDED
#define BEAST_CRYPTO_MURMURHASH_H_INCLUDED
#include <cstdint>
#include <stdexcept>
// Original source code links in .cpp file
namespace beast {
namespace Murmur {
extern void MurmurHash3_x86_32 (const void* key, int len, std::uint32_t seed, void* out);
extern void MurmurHash3_x86_128 (const void* key, int len, std::uint32_t seed, void* out);
extern void MurmurHash3_x64_128 (const void* key, int len, std::uint32_t seed, void* out);
// Uses Beast to choose an appropriate routine
// This handy template deduces which size hash is desired
template <typename HashType>
inline void Hash (const void* key, int len, std::uint32_t seed, HashType* out)
{
switch (8 * sizeof (HashType))
{
case 32:
MurmurHash3_x86_32 (key, len, seed, out);
break;
#if BEAST_64BIT
case 64:
{
HashType tmp[2];
MurmurHash3_x64_128 (key, len, seed, &tmp[0]);
*out = tmp[0];
}
break;
case 128:
MurmurHash3_x64_128 (key, len, seed, out);
break;
#else
case 64:
{
HashType tmp[2];
MurmurHash3_x86_128 (key, len, seed, &tmp[0]);
*out = tmp[0];
}
break;
case 128:
MurmurHash3_x86_128 (key, len, seed, out);
break;
#endif
default:
throw std::runtime_error ("invalid key size in MurmurHash");
break;
};
}
}
}
#endif

View File

@@ -1,492 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
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.
*/
//==============================================================================
// http://code.google.com/p/smhasher/
#include <beast/crypto/MurmurHash.h>
#include <cstdint>
namespace beast {
namespace Murmur {
//-----------------------------------------------------------------------------
// Platform-specific functions and macros
// Microsoft Visual Studio
#if BEAST_MSVC
#define ROTL32(x,y) _rotl(x,y)
#define ROTL64(x,y) _rotl64(x,y)
#define BIG_CONSTANT(x) (x)
// Other compilers
#else
static inline std::uint32_t rotl32 ( std::uint32_t x, int8_t r )
{
return (x << r) | (x >> (32 - r));
}
static inline std::uint64_t rotl64 ( std::uint64_t x, int8_t r )
{
return (x << r) | (x >> (64 - r));
}
#define ROTL32(x,y) rotl32(x,y)
#define ROTL64(x,y) rotl64(x,y)
#define BIG_CONSTANT(x) (x##LLU)
#endif
//-----------------------------------------------------------------------------
// Block read - if your platform needs to do endian-swapping or can only
// handle aligned reads, do the conversion here
static inline std::uint32_t getblock ( const std::uint32_t* p, int i )
{
return p[i];
}
static inline std::uint64_t getblock ( const std::uint64_t* p, int i )
{
return p[i];
}
//-----------------------------------------------------------------------------
// Finalization mix - force all bits of a hash block to avalanche
static inline std::uint32_t fmix ( std::uint32_t h )
{
h ^= h >> 16;
h *= 0x85ebca6b;
h ^= h >> 13;
h *= 0xc2b2ae35;
h ^= h >> 16;
return h;
}
//----------
static inline std::uint64_t fmix ( std::uint64_t k )
{
k ^= k >> 33;
k *= BIG_CONSTANT (0xff51afd7ed558ccd);
k ^= k >> 33;
k *= BIG_CONSTANT (0xc4ceb9fe1a85ec53);
k ^= k >> 33;
return k;
}
//-----------------------------------------------------------------------------
void MurmurHash3_x86_32 ( const void* key, int len,
std::uint32_t seed, void* out )
{
const uint8_t* data = (const uint8_t*)key;
const int nblocks = len / 4;
std::uint32_t h1 = seed;
std::uint32_t c1 = 0xcc9e2d51;
std::uint32_t c2 = 0x1b873593;
//----------
// body
const std::uint32_t* blocks = (const std::uint32_t*) (data + nblocks * 4);
for (int i = -nblocks; i; i++)
{
std::uint32_t k1 = getblock (blocks, i);
k1 *= c1;
k1 = ROTL32 (k1, 15);
k1 *= c2;
h1 ^= k1;
h1 = ROTL32 (h1, 13);
h1 = h1 * 5 + 0xe6546b64;
}
//----------
// tail
const uint8_t* tail = (const uint8_t*) (data + nblocks * 4);
std::uint32_t k1 = 0;
switch (len & 3)
{
case 3:
k1 ^= tail[2] << 16;
case 2:
k1 ^= tail[1] << 8;
case 1:
k1 ^= tail[0];
k1 *= c1;
k1 = ROTL32 (k1, 15);
k1 *= c2;
h1 ^= k1;
};
//----------
// finalization
h1 ^= len;
h1 = fmix (h1);
* (std::uint32_t*)out = h1;
}
//-----------------------------------------------------------------------------
void MurmurHash3_x86_128 ( const void* key, const int len,
std::uint32_t seed, void* out )
{
const uint8_t* data = (const uint8_t*)key;
const int nblocks = len / 16;
std::uint32_t h1 = seed;
std::uint32_t h2 = seed;
std::uint32_t h3 = seed;
std::uint32_t h4 = seed;
std::uint32_t c1 = 0x239b961b;
std::uint32_t c2 = 0xab0e9789;
std::uint32_t c3 = 0x38b34ae5;
std::uint32_t c4 = 0xa1e38b93;
//----------
// body
const std::uint32_t* blocks = (const std::uint32_t*) (data + nblocks * 16);
for (int i = -nblocks; i; i++)
{
std::uint32_t k1 = getblock (blocks, i * 4 + 0);
std::uint32_t k2 = getblock (blocks, i * 4 + 1);
std::uint32_t k3 = getblock (blocks, i * 4 + 2);
std::uint32_t k4 = getblock (blocks, i * 4 + 3);
k1 *= c1;
k1 = ROTL32 (k1, 15);
k1 *= c2;
h1 ^= k1;
h1 = ROTL32 (h1, 19);
h1 += h2;
h1 = h1 * 5 + 0x561ccd1b;
k2 *= c2;
k2 = ROTL32 (k2, 16);
k2 *= c3;
h2 ^= k2;
h2 = ROTL32 (h2, 17);
h2 += h3;
h2 = h2 * 5 + 0x0bcaa747;
k3 *= c3;
k3 = ROTL32 (k3, 17);
k3 *= c4;
h3 ^= k3;
h3 = ROTL32 (h3, 15);
h3 += h4;
h3 = h3 * 5 + 0x96cd1c35;
k4 *= c4;
k4 = ROTL32 (k4, 18);
k4 *= c1;
h4 ^= k4;
h4 = ROTL32 (h4, 13);
h4 += h1;
h4 = h4 * 5 + 0x32ac3b17;
}
//----------
// tail
const uint8_t* tail = (const uint8_t*) (data + nblocks * 16);
std::uint32_t k1 = 0;
std::uint32_t k2 = 0;
std::uint32_t k3 = 0;
std::uint32_t k4 = 0;
switch (len & 15)
{
case 15:
k4 ^= tail[14] << 16;
case 14:
k4 ^= tail[13] << 8;
case 13:
k4 ^= tail[12] << 0;
k4 *= c4;
k4 = ROTL32 (k4, 18);
k4 *= c1;
h4 ^= k4;
case 12:
k3 ^= tail[11] << 24;
case 11:
k3 ^= tail[10] << 16;
case 10:
k3 ^= tail[ 9] << 8;
case 9:
k3 ^= tail[ 8] << 0;
k3 *= c3;
k3 = ROTL32 (k3, 17);
k3 *= c4;
h3 ^= k3;
case 8:
k2 ^= tail[ 7] << 24;
case 7:
k2 ^= tail[ 6] << 16;
case 6:
k2 ^= tail[ 5] << 8;
case 5:
k2 ^= tail[ 4] << 0;
k2 *= c2;
k2 = ROTL32 (k2, 16);
k2 *= c3;
h2 ^= k2;
case 4:
k1 ^= tail[ 3] << 24;
case 3:
k1 ^= tail[ 2] << 16;
case 2:
k1 ^= tail[ 1] << 8;
case 1:
k1 ^= tail[ 0] << 0;
k1 *= c1;
k1 = ROTL32 (k1, 15);
k1 *= c2;
h1 ^= k1;
};
//----------
// finalization
h1 ^= len;
h2 ^= len;
h3 ^= len;
h4 ^= len;
h1 += h2;
h1 += h3;
h1 += h4;
h2 += h1;
h3 += h1;
h4 += h1;
h1 = fmix (h1);
h2 = fmix (h2);
h3 = fmix (h3);
h4 = fmix (h4);
h1 += h2;
h1 += h3;
h1 += h4;
h2 += h1;
h3 += h1;
h4 += h1;
((std::uint32_t*)out)[0] = h1;
((std::uint32_t*)out)[1] = h2;
((std::uint32_t*)out)[2] = h3;
((std::uint32_t*)out)[3] = h4;
}
//-----------------------------------------------------------------------------
void MurmurHash3_x64_128 ( const void* key, const int len,
const std::uint32_t seed, void* out )
{
const uint8_t* data = (const uint8_t*)key;
const int nblocks = len / 16;
std::uint64_t h1 = seed;
std::uint64_t h2 = seed;
std::uint64_t c1 = BIG_CONSTANT (0x87c37b91114253d5);
std::uint64_t c2 = BIG_CONSTANT (0x4cf5ad432745937f);
//----------
// body
const std::uint64_t* blocks = (const std::uint64_t*) (data);
for (int i = 0; i < nblocks; i++)
{
std::uint64_t k1 = getblock (blocks, i * 2 + 0);
std::uint64_t k2 = getblock (blocks, i * 2 + 1);
k1 *= c1;
k1 = ROTL64 (k1, 31);
k1 *= c2;
h1 ^= k1;
h1 = ROTL64 (h1, 27);
h1 += h2;
h1 = h1 * 5 + 0x52dce729;
k2 *= c2;
k2 = ROTL64 (k2, 33);
k2 *= c1;
h2 ^= k2;
h2 = ROTL64 (h2, 31);
h2 += h1;
h2 = h2 * 5 + 0x38495ab5;
}
//----------
// tail
const uint8_t* tail = (const uint8_t*) (data + nblocks * 16);
std::uint64_t k1 = 0;
std::uint64_t k2 = 0;
switch (len & 15)
{
case 15:
k2 ^= std::uint64_t (tail[14]) << 48;
case 14:
k2 ^= std::uint64_t (tail[13]) << 40;
case 13:
k2 ^= std::uint64_t (tail[12]) << 32;
case 12:
k2 ^= std::uint64_t (tail[11]) << 24;
case 11:
k2 ^= std::uint64_t (tail[10]) << 16;
case 10:
k2 ^= std::uint64_t (tail[ 9]) << 8;
case 9:
k2 ^= std::uint64_t (tail[ 8]) << 0;
k2 *= c2;
k2 = ROTL64 (k2, 33);
k2 *= c1;
h2 ^= k2;
case 8:
k1 ^= std::uint64_t (tail[ 7]) << 56;
case 7:
k1 ^= std::uint64_t (tail[ 6]) << 48;
case 6:
k1 ^= std::uint64_t (tail[ 5]) << 40;
case 5:
k1 ^= std::uint64_t (tail[ 4]) << 32;
case 4:
k1 ^= std::uint64_t (tail[ 3]) << 24;
case 3:
k1 ^= std::uint64_t (tail[ 2]) << 16;
case 2:
k1 ^= std::uint64_t (tail[ 1]) << 8;
case 1:
k1 ^= std::uint64_t (tail[ 0]) << 0;
k1 *= c1;
k1 = ROTL64 (k1, 31);
k1 *= c2;
h1 ^= k1;
};
//----------
// finalization
h1 ^= len;
h2 ^= len;
h1 += h2;
h2 += h1;
h1 = fmix (h1);
h2 = fmix (h2);
h1 += h2;
h2 += h1;
((std::uint64_t*)out)[0] = h1;
((std::uint64_t*)out)[1] = h2;
}
}
}

View File

@@ -32,8 +32,8 @@
* $Id: sha2.h,v 1.1 2001/11/08 00:02:01 adg Exp adg $
*/
#ifndef __SHA2_H__
#define __SHA2_H__
#ifndef BEAST_CRYPTO_SHA2_SHA2_H_INCLUDED
#define BEAST_CRYPTO_SHA2_SHA2_H_INCLUDED
//#ifdef __cplusplus
//extern "C" {

View File

@@ -0,0 +1,71 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2014, Howard Hinnant <howard.hinnant@gmail.com>,
Vinnie Falco <vinnie.falco@gmail.com
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 BEAST_HASH_FNV1A_H_INCLUDED
#define BEAST_HASH_FNV1A_H_INCLUDED
#include <beast/utility/noexcept.h>
#include <cstddef>
#include <cstdint>
#include <beast/cxx14/type_traits.h> // <type_traits>
namespace beast {
// See http://www.isthe.com/chongo/tech/comp/fnv/
//
class fnv1a
{
private:
std::uint64_t state_ = 14695981039346656037ULL;
public:
using result_type = std::size_t;
fnv1a() = default;
template <class Seed,
std::enable_if_t<
std::is_unsigned<Seed>::value>* = nullptr>
explicit
fnv1a (Seed seed)
{
append (&seed, sizeof(seed));
}
void
append (void const* key, std::size_t len) noexcept
{
unsigned char const* p =
static_cast<unsigned char const*>(key);
unsigned char const* const e = p + len;
for (; p < e; ++p)
state_ = (state_ ^ *p) * 1099511628211ULL;
}
explicit
operator std::size_t() noexcept
{
return static_cast<std::size_t>(state_);
}
};
} // beast
#endif

View File

@@ -18,18 +18,14 @@
*/
//==============================================================================
#ifndef BEAST_CONTAINER_HASH_APPEND_H_INCLUDED
#define BEAST_CONTAINER_HASH_APPEND_H_INCLUDED
#ifndef BEAST_HASH_HASH_APPEND_H_INCLUDED
#define BEAST_HASH_HASH_APPEND_H_INCLUDED
#include <beast/utility/meta.h>
#include <beast/container/impl/spookyv2.h>
#include <beast/utility/noexcept.h>
#if BEAST_USE_BOOST_FEATURES
#include <boost/shared_ptr.hpp>
#endif
#include <beast/utility/noexcept.h>
#include <array>
#include <cstdint>
#include <functional>
@@ -656,96 +652,6 @@ hash_append (Hasher& h, T0 const& t0, T1 const& t1, T const& ...t) noexcept
hash_append (h, t1, t...);
}
// See http://www.isthe.com/chongo/tech/comp/fnv/
class fnv1a
{
std::uint64_t state_ = 14695981039346656037ULL;
public:
using result_type = std::size_t;
void
append (void const* key, std::size_t len) noexcept
{
unsigned char const* p = static_cast<unsigned char const*>(key);
unsigned char const* const e = p + len;
for (; p < e; ++p)
state_ = (state_ ^ *p) * 1099511628211ULL;
}
explicit
operator std::size_t() noexcept
{
return static_cast<std::size_t>(state_);
}
};
// See http://burtleburtle.net/bob/hash/spooky.html
class spooky
{
SpookyHash state_;
public:
using result_type = std::size_t;
spooky (std::size_t seed1 = 1, std::size_t seed2 = 2) noexcept
{
state_.Init (seed1, seed2);
}
void
append (void const* key, std::size_t len) noexcept
{
state_.Update (key, len);
}
explicit
operator std::size_t() noexcept
{
std::uint64_t h1, h2;
state_.Final (&h1, &h2);
return static_cast <std::size_t> (h1);
}
};
// See https://131002.net/siphash/
class siphash
{
std::uint64_t v0_ = 0x736f6d6570736575ULL;
std::uint64_t v1_ = 0x646f72616e646f6dULL;
std::uint64_t v2_ = 0x6c7967656e657261ULL;
std::uint64_t v3_ = 0x7465646279746573ULL;
unsigned char buf_[8];
unsigned bufsize_ = 0;
unsigned total_length_ = 0;
public:
using result_type = std::size_t;
siphash() = default;
explicit siphash(std::uint64_t k0, std::uint64_t k1 = 0) noexcept;
void
append (void const* key, std::size_t len) noexcept;
explicit
operator std::size_t() noexcept;
};
template <class Hasher = spooky>
struct uhash
{
using result_type = typename Hasher::result_type;
template <class T>
result_type
operator()(T const& t) const noexcept
{
Hasher h;
hash_append (h, t);
return static_cast<result_type>(h);
}
};
} // beast
#endif

View File

@@ -0,0 +1,85 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
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.
*/
//==============================================================================
#if BEAST_INCLUDE_BEASTCONFIG
#include <BeastConfig.h>
#endif
#include <beast/container/fnv1a.h>
#include <beast/container/siphash.h>
#include <beast/container/xxhasher.h>
#include <beast/random/rngfill.h>
#include <beast/random/xor_shift_engine.h>
#include <beast/unit_test/suite.h>
#include <array>
#include <chrono>
#include <cstdint>
#include <cstring>
#include <iomanip>
#include <random>
namespace beast {
class hash_speed_test : public beast::unit_test::suite
{
public:
using clock_type =
std::chrono::high_resolution_clock;
template <class Hasher, std::size_t KeySize>
void
test (std::string const& what, std::size_t n)
{
using namespace std;
using namespace std::chrono;
xor_shift_engine g(1);
array<std::uint8_t, KeySize> key;
auto const start = clock_type::now();
while(n--)
{
rngfill (key, g);
Hasher h;
h.append(key.data(), KeySize);
volatile size_t temp =
static_cast<std::size_t>(h);
(void)temp;
}
auto const elapsed = clock_type::now() - start;
log << setw(12) << what << " " <<
duration<double>(elapsed) << "s";
}
void
run()
{
enum
{
N = 100000000
};
#if ! BEAST_NO_XXHASH
test<xxhasher,32> ("xxhash", N);
#endif
test<fnv1a,32> ("fnv1a", N);
test<siphash,32> ("siphash", N);
pass();
}
};
BEAST_DEFINE_TESTSUITE_MANUAL(hash_speed,container,beast);
} // beast

View File

@@ -24,18 +24,15 @@
//
//------------------------------------------------------------------------------
#include <beast/container/hash_append.h>
#include <beast/hash/siphash.h>
#include <algorithm>
#include <cstddef>
#include <cstdint>
// namespace acme is used to demonstrate example code. It is not proposed.
namespace beast
{
namespace
{
namespace beast {
namespace detail {
typedef std::uint64_t u64;
typedef std::uint32_t u32;
@@ -82,7 +79,7 @@ sipround(u64& v0, u64& v1, u64& v2, u64& v3)
v2 = rotl(v2, 32);
}
} // unnamed
} // detail
siphash::siphash(std::uint64_t k0, std::uint64_t k1) noexcept
{
@@ -95,6 +92,7 @@ siphash::siphash(std::uint64_t k0, std::uint64_t k1) noexcept
void
siphash::append (void const* key, std::size_t inlen) noexcept
{
using namespace detail;
u8 const* in = static_cast<const u8*>(key);
total_length_ += inlen;
if (bufsize_ + inlen < 8)
@@ -130,6 +128,7 @@ siphash::append (void const* key, std::size_t inlen) noexcept
siphash::operator std::size_t() noexcept
{
using namespace detail;
std::size_t b = static_cast<u64>(total_length_) << 56;
switch(bufsize_)
{
@@ -163,4 +162,4 @@ siphash::operator std::size_t() noexcept
return b;
}
} // beast
} // beast

View File

@@ -10,7 +10,7 @@
// August 5 2012: SpookyV2: d = should be d += in short hash, and remove extra mix from long hash
#include <memory.h>
#include <beast/container/impl/spookyv2.h>
#include <beast/hash/impl/spookyv2.h>
#ifdef _MSC_VER
#pragma warning (push)

View File

@@ -26,8 +26,8 @@
// slower than MD5.
//
#ifndef BEAST_SPOOKYV2_H_INCLUDED
#define BEAST_SPOOKYV2_H_INCLUDED
#ifndef BEAST_HASH_SPOOKYV2_H_INCLUDED
#define BEAST_HASH_SPOOKYV2_H_INCLUDED
#include <stddef.h>

View File

@@ -0,0 +1,934 @@
/*
xxHash - Fast Hash algorithm
Copyright (C) 2012-2014, Yann Collet.
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
You can contact the author at :
- xxHash source repository : http://code.google.com/p/xxhash/
- public discussion board : https://groups.google.com/forum/#!forum/lz4c
*/
#include <beast/hash/impl/xxhash.h>
//**************************************
// Tuning parameters
//**************************************
// Unaligned memory access is automatically enabled for "common" CPU, such as x86.
// For others CPU, the compiler will be more cautious, and insert extra code to ensure aligned access is respected.
// If you know your target CPU supports unaligned memory access, you want to force this option manually to improve performance.
// You can also enable this parameter if you know your input data will always be aligned (boundaries of 4, for U32).
#if defined(__ARM_FEATURE_UNALIGNED) || defined(__i386) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64)
# define XXH_USE_UNALIGNED_ACCESS 1
#endif
// XXH_ACCEPT_NULL_INPUT_POINTER :
// If the input pointer is a null pointer, xxHash default behavior is to trigger a memory access error, since it is a bad pointer.
// When this option is enabled, xxHash output for null input pointers will be the same as a null-length input.
// This option has a very small performance cost (only measurable on small inputs).
// By default, this option is disabled. To enable it, uncomment below define :
// #define XXH_ACCEPT_NULL_INPUT_POINTER 1
// XXH_FORCE_NATIVE_FORMAT :
// By default, xxHash library provides endian-independant Hash values, based on little-endian convention.
// Results are therefore identical for little-endian and big-endian CPU.
// This comes at a performance cost for big-endian CPU, since some swapping is required to emulate little-endian format.
// Should endian-independance be of no importance for your application, you may set the #define below to 1.
// It will improve speed for Big-endian CPU.
// This option has no impact on Little_Endian CPU.
#define XXH_FORCE_NATIVE_FORMAT 0
//**************************************
// Compiler Specific Options
//**************************************
// Disable some Visual warning messages
#ifdef _MSC_VER // Visual Studio
# pragma warning(disable : 4127) // disable: C4127: conditional expression is constant
#endif
#ifdef _MSC_VER // Visual Studio
# define FORCE_INLINE static __forceinline
#else
# ifdef __GNUC__
# define FORCE_INLINE static inline __attribute__((always_inline))
# else
# define FORCE_INLINE static inline
# endif
#endif
//**************************************
// Includes & Memory related functions
//**************************************
//#include "xxhash.h"
// Modify the local functions below should you wish to use some other memory routines
// for malloc(), free()
#include <stdlib.h>
static void* XXH_malloc(size_t s) { return malloc(s); }
static void XXH_free (void* p) { free(p); }
// for memcpy()
#include <string.h>
static void* XXH_memcpy(void* dest, const void* src, size_t size)
{
return memcpy(dest,src,size);
}
//**************************************
// Basic Types
//**************************************
#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L // C99
# include <stdint.h>
typedef uint8_t BYTE;
typedef uint16_t U16;
typedef uint32_t U32;
typedef int32_t S32;
typedef uint64_t U64;
#else
typedef unsigned char BYTE;
typedef unsigned short U16;
typedef unsigned int U32;
typedef signed int S32;
typedef unsigned long long U64;
#endif
#if defined(__GNUC__) && !defined(XXH_USE_UNALIGNED_ACCESS)
# define _PACKED __attribute__ ((packed))
#else
# define _PACKED
#endif
#if !defined(XXH_USE_UNALIGNED_ACCESS) && !defined(__GNUC__)
# ifdef __IBMC__
# pragma pack(1)
# else
# pragma pack(push, 1)
# endif
#endif
namespace beast {
namespace detail {
typedef struct _U32_S
{
U32 v;
} _PACKED U32_S;
typedef struct _U64_S
{
U64 v;
} _PACKED U64_S;
#if !defined(XXH_USE_UNALIGNED_ACCESS) && !defined(__GNUC__)
# pragma pack(pop)
#endif
#define A32(x) (((U32_S *)(x))->v)
#define A64(x) (((U64_S *)(x))->v)
//***************************************
// Compiler-specific Functions and Macros
//***************************************
#define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
// Note : although _rotl exists for minGW (GCC under windows), performance seems poor
#if defined(_MSC_VER)
# define XXH_rotl32(x,r) _rotl(x,r)
# define XXH_rotl64(x,r) _rotl64(x,r)
#else
# define XXH_rotl32(x,r) ((x << r) | (x >> (32 - r)))
# define XXH_rotl64(x,r) ((x << r) | (x >> (64 - r)))
#endif
#if defined(_MSC_VER) // Visual Studio
# define XXH_swap32 _byteswap_ulong
# define XXH_swap64 _byteswap_uint64
#elif GCC_VERSION >= 403
# define XXH_swap32 __builtin_bswap32
# define XXH_swap64 __builtin_bswap64
#else
static inline U32 XXH_swap32 (U32 x)
{
return ((x << 24) & 0xff000000 ) |
((x << 8) & 0x00ff0000 ) |
((x >> 8) & 0x0000ff00 ) |
((x >> 24) & 0x000000ff );
}
static inline U64 XXH_swap64 (U64 x)
{
return ((x << 56) & 0xff00000000000000ULL) |
((x << 40) & 0x00ff000000000000ULL) |
((x << 24) & 0x0000ff0000000000ULL) |
((x << 8) & 0x000000ff00000000ULL) |
((x >> 8) & 0x00000000ff000000ULL) |
((x >> 24) & 0x0000000000ff0000ULL) |
((x >> 40) & 0x000000000000ff00ULL) |
((x >> 56) & 0x00000000000000ffULL);
}
#endif
//**************************************
// Constants
//**************************************
#define PRIME32_1 2654435761U
#define PRIME32_2 2246822519U
#define PRIME32_3 3266489917U
#define PRIME32_4 668265263U
#define PRIME32_5 374761393U
#define PRIME64_1 11400714785074694791ULL
#define PRIME64_2 14029467366897019727ULL
#define PRIME64_3 1609587929392839161ULL
#define PRIME64_4 9650029242287828579ULL
#define PRIME64_5 2870177450012600261ULL
//**************************************
// Architecture Macros
//**************************************
typedef enum { XXH_bigEndian=0, XXH_littleEndian=1 } XXH_endianess;
#ifndef XXH_CPU_LITTLE_ENDIAN // It is possible to define XXH_CPU_LITTLE_ENDIAN externally, for example using a compiler switch
static const int one = 1;
# define XXH_CPU_LITTLE_ENDIAN (*(char*)(&one))
#endif
//**************************************
// Macros
//**************************************
#define XXH_STATIC_ASSERT(c) { enum { XXH_static_assert = 1/(!!(c)) }; } // use only *after* variable declarations
//****************************
// Memory reads
//****************************
typedef enum { XXH_aligned, XXH_unaligned } XXH_alignment;
FORCE_INLINE U32 XXH_readLE32_align(const void* ptr, XXH_endianess endian, XXH_alignment align)
{
if (align==XXH_unaligned)
return endian==XXH_littleEndian ? A32(ptr) : XXH_swap32(A32(ptr));
else
return endian==XXH_littleEndian ? *(U32*)ptr : XXH_swap32(*(U32*)ptr);
}
FORCE_INLINE U32 XXH_readLE32(const void* ptr, XXH_endianess endian)
{
return XXH_readLE32_align(ptr, endian, XXH_unaligned);
}
FORCE_INLINE U64 XXH_readLE64_align(const void* ptr, XXH_endianess endian, XXH_alignment align)
{
if (align==XXH_unaligned)
return endian==XXH_littleEndian ? A64(ptr) : XXH_swap64(A64(ptr));
else
return endian==XXH_littleEndian ? *(U64*)ptr : XXH_swap64(*(U64*)ptr);
}
FORCE_INLINE U64 XXH_readLE64(const void* ptr, XXH_endianess endian)
{
return XXH_readLE64_align(ptr, endian, XXH_unaligned);
}
//****************************
// Simple Hash Functions
//****************************
FORCE_INLINE U32 XXH32_endian_align(const void* input, size_t len, U32 seed, XXH_endianess endian, XXH_alignment align)
{
const BYTE* p = (const BYTE*)input;
const BYTE* bEnd = p + len;
U32 h32;
#define XXH_get32bits(p) XXH_readLE32_align(p, endian, align)
#ifdef XXH_ACCEPT_NULL_INPUT_POINTER
if (p==NULL)
{
len=0;
bEnd=p=(const BYTE*)(size_t)16;
}
#endif
if (len>=16)
{
const BYTE* const limit = bEnd - 16;
U32 v1 = seed + PRIME32_1 + PRIME32_2;
U32 v2 = seed + PRIME32_2;
U32 v3 = seed + 0;
U32 v4 = seed - PRIME32_1;
do
{
v1 += XXH_get32bits(p) * PRIME32_2;
v1 = XXH_rotl32(v1, 13);
v1 *= PRIME32_1;
p+=4;
v2 += XXH_get32bits(p) * PRIME32_2;
v2 = XXH_rotl32(v2, 13);
v2 *= PRIME32_1;
p+=4;
v3 += XXH_get32bits(p) * PRIME32_2;
v3 = XXH_rotl32(v3, 13);
v3 *= PRIME32_1;
p+=4;
v4 += XXH_get32bits(p) * PRIME32_2;
v4 = XXH_rotl32(v4, 13);
v4 *= PRIME32_1;
p+=4;
}
while (p<=limit);
h32 = XXH_rotl32(v1, 1) + XXH_rotl32(v2, 7) + XXH_rotl32(v3, 12) + XXH_rotl32(v4, 18);
}
else
{
h32 = seed + PRIME32_5;
}
h32 += (U32) len;
while (p+4<=bEnd)
{
h32 += XXH_get32bits(p) * PRIME32_3;
h32 = XXH_rotl32(h32, 17) * PRIME32_4 ;
p+=4;
}
while (p<bEnd)
{
h32 += (*p) * PRIME32_5;
h32 = XXH_rotl32(h32, 11) * PRIME32_1 ;
p++;
}
h32 ^= h32 >> 15;
h32 *= PRIME32_2;
h32 ^= h32 >> 13;
h32 *= PRIME32_3;
h32 ^= h32 >> 16;
return h32;
}
unsigned int XXH32 (const void* input, size_t len, unsigned seed)
{
#if 0
// Simple version, good for code maintenance, but unfortunately slow for small inputs
XXH32_state_t state;
XXH32_reset(&state, seed);
XXH32_update(&state, input, len);
return XXH32_digest(&state);
#else
XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
# if !defined(XXH_USE_UNALIGNED_ACCESS)
if ((((size_t)input) & 3) == 0) // Input is aligned, let's leverage the speed advantage
{
if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned);
else
return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned);
}
# endif
if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned);
else
return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_unaligned);
#endif
}
FORCE_INLINE U64 XXH64_endian_align(const void* input, size_t len, U64 seed, XXH_endianess endian, XXH_alignment align)
{
const BYTE* p = (const BYTE*)input;
const BYTE* bEnd = p + len;
U64 h64;
#define XXH_get64bits(p) XXH_readLE64_align(p, endian, align)
#ifdef XXH_ACCEPT_NULL_INPUT_POINTER
if (p==NULL)
{
len=0;
bEnd=p=(const BYTE*)(size_t)32;
}
#endif
if (len>=32)
{
const BYTE* const limit = bEnd - 32;
U64 v1 = seed + PRIME64_1 + PRIME64_2;
U64 v2 = seed + PRIME64_2;
U64 v3 = seed + 0;
U64 v4 = seed - PRIME64_1;
do
{
v1 += XXH_get64bits(p) * PRIME64_2;
p+=8;
v1 = XXH_rotl64(v1, 31);
v1 *= PRIME64_1;
v2 += XXH_get64bits(p) * PRIME64_2;
p+=8;
v2 = XXH_rotl64(v2, 31);
v2 *= PRIME64_1;
v3 += XXH_get64bits(p) * PRIME64_2;
p+=8;
v3 = XXH_rotl64(v3, 31);
v3 *= PRIME64_1;
v4 += XXH_get64bits(p) * PRIME64_2;
p+=8;
v4 = XXH_rotl64(v4, 31);
v4 *= PRIME64_1;
}
while (p<=limit);
h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18);
v1 *= PRIME64_2;
v1 = XXH_rotl64(v1, 31);
v1 *= PRIME64_1;
h64 ^= v1;
h64 = h64 * PRIME64_1 + PRIME64_4;
v2 *= PRIME64_2;
v2 = XXH_rotl64(v2, 31);
v2 *= PRIME64_1;
h64 ^= v2;
h64 = h64 * PRIME64_1 + PRIME64_4;
v3 *= PRIME64_2;
v3 = XXH_rotl64(v3, 31);
v3 *= PRIME64_1;
h64 ^= v3;
h64 = h64 * PRIME64_1 + PRIME64_4;
v4 *= PRIME64_2;
v4 = XXH_rotl64(v4, 31);
v4 *= PRIME64_1;
h64 ^= v4;
h64 = h64 * PRIME64_1 + PRIME64_4;
}
else
{
h64 = seed + PRIME64_5;
}
h64 += (U64) len;
while (p+8<=bEnd)
{
U64 k1 = XXH_get64bits(p);
k1 *= PRIME64_2;
k1 = XXH_rotl64(k1,31);
k1 *= PRIME64_1;
h64 ^= k1;
h64 = XXH_rotl64(h64,27) * PRIME64_1 + PRIME64_4;
p+=8;
}
if (p+4<=bEnd)
{
h64 ^= (U64)(XXH_get32bits(p)) * PRIME64_1;
h64 = XXH_rotl64(h64, 23) * PRIME64_2 + PRIME64_3;
p+=4;
}
while (p<bEnd)
{
h64 ^= (*p) * PRIME64_5;
h64 = XXH_rotl64(h64, 11) * PRIME64_1;
p++;
}
h64 ^= h64 >> 33;
h64 *= PRIME64_2;
h64 ^= h64 >> 29;
h64 *= PRIME64_3;
h64 ^= h64 >> 32;
return h64;
}
unsigned long long XXH64 (const void* input, size_t len, unsigned long long seed)
{
#if 0
// Simple version, good for code maintenance, but unfortunately slow for small inputs
XXH64_state_t state;
XXH64_reset(&state, seed);
XXH64_update(&state, input, len);
return XXH64_digest(&state);
#else
XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
# if !defined(XXH_USE_UNALIGNED_ACCESS)
if ((((size_t)input) & 7)==0) // Input is aligned, let's leverage the speed advantage
{
if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
return XXH64_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned);
else
return XXH64_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned);
}
# endif
if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
return XXH64_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned);
else
return XXH64_endian_align(input, len, seed, XXH_bigEndian, XXH_unaligned);
#endif
}
/****************************************************
* Advanced Hash Functions
****************************************************/
/*** Allocation ***/
typedef struct
{
U64 total_len;
U32 seed;
U32 v1;
U32 v2;
U32 v3;
U32 v4;
U32 mem32[4]; /* defined as U32 for alignment */
U32 memsize;
} XXH_istate32_t;
typedef struct
{
U64 total_len;
U64 seed;
U64 v1;
U64 v2;
U64 v3;
U64 v4;
U64 mem64[4]; /* defined as U64 for alignment */
U32 memsize;
} XXH_istate64_t;
XXH32_state_t* XXH32_createState(void)
{
static_assert(sizeof(XXH32_state_t) >= sizeof(XXH_istate32_t), ""); // A compilation error here means XXH32_state_t is not large enough
return (XXH32_state_t*)XXH_malloc(sizeof(XXH32_state_t));
}
XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr)
{
XXH_free(statePtr);
return XXH_OK;
};
XXH64_state_t* XXH64_createState(void)
{
static_assert(sizeof(XXH64_state_t) >= sizeof(XXH_istate64_t), ""); // A compilation error here means XXH64_state_t is not large enough
return (XXH64_state_t*)XXH_malloc(sizeof(XXH64_state_t));
}
XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr)
{
XXH_free(statePtr);
return XXH_OK;
};
/*** Hash feed ***/
XXH_errorcode XXH32_reset(XXH32_state_t* state_in, U32 seed)
{
XXH_istate32_t* state = (XXH_istate32_t*) state_in;
state->seed = seed;
state->v1 = seed + PRIME32_1 + PRIME32_2;
state->v2 = seed + PRIME32_2;
state->v3 = seed + 0;
state->v4 = seed - PRIME32_1;
state->total_len = 0;
state->memsize = 0;
return XXH_OK;
}
XXH_errorcode XXH64_reset(XXH64_state_t* state_in, unsigned long long seed)
{
XXH_istate64_t* state = (XXH_istate64_t*) state_in;
state->seed = seed;
state->v1 = seed + PRIME64_1 + PRIME64_2;
state->v2 = seed + PRIME64_2;
state->v3 = seed + 0;
state->v4 = seed - PRIME64_1;
state->total_len = 0;
state->memsize = 0;
return XXH_OK;
}
FORCE_INLINE XXH_errorcode XXH32_update_endian (XXH32_state_t* state_in, const void* input, size_t len, XXH_endianess endian)
{
XXH_istate32_t* state = (XXH_istate32_t *) state_in;
const BYTE* p = (const BYTE*)input;
const BYTE* const bEnd = p + len;
#ifdef XXH_ACCEPT_NULL_INPUT_POINTER
if (input==NULL) return XXH_ERROR;
#endif
state->total_len += len;
if (state->memsize + len < 16) // fill in tmp buffer
{
XXH_memcpy((BYTE*)(state->mem32) + state->memsize, input, len);
state->memsize += (U32)len;
return XXH_OK;
}
if (state->memsize) // some data left from previous update
{
XXH_memcpy((BYTE*)(state->mem32) + state->memsize, input, 16-state->memsize);
{
const U32* p32 = state->mem32;
state->v1 += XXH_readLE32(p32, endian) * PRIME32_2;
state->v1 = XXH_rotl32(state->v1, 13);
state->v1 *= PRIME32_1;
p32++;
state->v2 += XXH_readLE32(p32, endian) * PRIME32_2;
state->v2 = XXH_rotl32(state->v2, 13);
state->v2 *= PRIME32_1;
p32++;
state->v3 += XXH_readLE32(p32, endian) * PRIME32_2;
state->v3 = XXH_rotl32(state->v3, 13);
state->v3 *= PRIME32_1;
p32++;
state->v4 += XXH_readLE32(p32, endian) * PRIME32_2;
state->v4 = XXH_rotl32(state->v4, 13);
state->v4 *= PRIME32_1;
p32++;
}
p += 16-state->memsize;
state->memsize = 0;
}
if (p <= bEnd-16)
{
const BYTE* const limit = bEnd - 16;
U32 v1 = state->v1;
U32 v2 = state->v2;
U32 v3 = state->v3;
U32 v4 = state->v4;
do
{
v1 += XXH_readLE32(p, endian) * PRIME32_2;
v1 = XXH_rotl32(v1, 13);
v1 *= PRIME32_1;
p+=4;
v2 += XXH_readLE32(p, endian) * PRIME32_2;
v2 = XXH_rotl32(v2, 13);
v2 *= PRIME32_1;
p+=4;
v3 += XXH_readLE32(p, endian) * PRIME32_2;
v3 = XXH_rotl32(v3, 13);
v3 *= PRIME32_1;
p+=4;
v4 += XXH_readLE32(p, endian) * PRIME32_2;
v4 = XXH_rotl32(v4, 13);
v4 *= PRIME32_1;
p+=4;
}
while (p<=limit);
state->v1 = v1;
state->v2 = v2;
state->v3 = v3;
state->v4 = v4;
}
if (p < bEnd)
{
XXH_memcpy(state->mem32, p, bEnd-p);
state->memsize = (int)(bEnd-p);
}
return XXH_OK;
}
XXH_errorcode XXH32_update (XXH32_state_t* state_in, const void* input, size_t len)
{
XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
return XXH32_update_endian(state_in, input, len, XXH_littleEndian);
else
return XXH32_update_endian(state_in, input, len, XXH_bigEndian);
}
FORCE_INLINE U32 XXH32_digest_endian (const XXH32_state_t* state_in, XXH_endianess endian)
{
XXH_istate32_t* state = (XXH_istate32_t*) state_in;
const BYTE * p = (const BYTE*)state->mem32;
BYTE* bEnd = (BYTE*)(state->mem32) + state->memsize;
U32 h32;
if (state->total_len >= 16)
{
h32 = XXH_rotl32(state->v1, 1) + XXH_rotl32(state->v2, 7) + XXH_rotl32(state->v3, 12) + XXH_rotl32(state->v4, 18);
}
else
{
h32 = state->seed + PRIME32_5;
}
h32 += (U32) state->total_len;
while (p+4<=bEnd)
{
h32 += XXH_readLE32(p, endian) * PRIME32_3;
h32 = XXH_rotl32(h32, 17) * PRIME32_4;
p+=4;
}
while (p<bEnd)
{
h32 += (*p) * PRIME32_5;
h32 = XXH_rotl32(h32, 11) * PRIME32_1;
p++;
}
h32 ^= h32 >> 15;
h32 *= PRIME32_2;
h32 ^= h32 >> 13;
h32 *= PRIME32_3;
h32 ^= h32 >> 16;
return h32;
}
U32 XXH32_digest (const XXH32_state_t* state_in)
{
XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
return XXH32_digest_endian(state_in, XXH_littleEndian);
else
return XXH32_digest_endian(state_in, XXH_bigEndian);
}
FORCE_INLINE XXH_errorcode XXH64_update_endian (XXH64_state_t* state_in, const void* input, size_t len, XXH_endianess endian)
{
XXH_istate64_t * state = (XXH_istate64_t *) state_in;
const BYTE* p = (const BYTE*)input;
const BYTE* const bEnd = p + len;
#ifdef XXH_ACCEPT_NULL_INPUT_POINTER
if (input==NULL) return XXH_ERROR;
#endif
state->total_len += len;
if (state->memsize + len < 32) // fill in tmp buffer
{
XXH_memcpy(((BYTE*)state->mem64) + state->memsize, input, len);
state->memsize += (U32)len;
return XXH_OK;
}
if (state->memsize) // some data left from previous update
{
XXH_memcpy(((BYTE*)state->mem64) + state->memsize, input, 32-state->memsize);
{
const U64* p64 = state->mem64;
state->v1 += XXH_readLE64(p64, endian) * PRIME64_2;
state->v1 = XXH_rotl64(state->v1, 31);
state->v1 *= PRIME64_1;
p64++;
state->v2 += XXH_readLE64(p64, endian) * PRIME64_2;
state->v2 = XXH_rotl64(state->v2, 31);
state->v2 *= PRIME64_1;
p64++;
state->v3 += XXH_readLE64(p64, endian) * PRIME64_2;
state->v3 = XXH_rotl64(state->v3, 31);
state->v3 *= PRIME64_1;
p64++;
state->v4 += XXH_readLE64(p64, endian) * PRIME64_2;
state->v4 = XXH_rotl64(state->v4, 31);
state->v4 *= PRIME64_1;
p64++;
}
p += 32-state->memsize;
state->memsize = 0;
}
if (p+32 <= bEnd)
{
const BYTE* const limit = bEnd - 32;
U64 v1 = state->v1;
U64 v2 = state->v2;
U64 v3 = state->v3;
U64 v4 = state->v4;
do
{
v1 += XXH_readLE64(p, endian) * PRIME64_2;
v1 = XXH_rotl64(v1, 31);
v1 *= PRIME64_1;
p+=8;
v2 += XXH_readLE64(p, endian) * PRIME64_2;
v2 = XXH_rotl64(v2, 31);
v2 *= PRIME64_1;
p+=8;
v3 += XXH_readLE64(p, endian) * PRIME64_2;
v3 = XXH_rotl64(v3, 31);
v3 *= PRIME64_1;
p+=8;
v4 += XXH_readLE64(p, endian) * PRIME64_2;
v4 = XXH_rotl64(v4, 31);
v4 *= PRIME64_1;
p+=8;
}
while (p<=limit);
state->v1 = v1;
state->v2 = v2;
state->v3 = v3;
state->v4 = v4;
}
if (p < bEnd)
{
XXH_memcpy(state->mem64, p, bEnd-p);
state->memsize = (int)(bEnd-p);
}
return XXH_OK;
}
XXH_errorcode XXH64_update (XXH64_state_t* state_in, const void* input, size_t len)
{
XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
return XXH64_update_endian(state_in, input, len, XXH_littleEndian);
else
return XXH64_update_endian(state_in, input, len, XXH_bigEndian);
}
FORCE_INLINE U64 XXH64_digest_endian (const XXH64_state_t* state_in, XXH_endianess endian)
{
XXH_istate64_t * state = (XXH_istate64_t *) state_in;
const BYTE * p = (const BYTE*)state->mem64;
BYTE* bEnd = (BYTE*)state->mem64 + state->memsize;
U64 h64;
if (state->total_len >= 32)
{
U64 v1 = state->v1;
U64 v2 = state->v2;
U64 v3 = state->v3;
U64 v4 = state->v4;
h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18);
v1 *= PRIME64_2;
v1 = XXH_rotl64(v1, 31);
v1 *= PRIME64_1;
h64 ^= v1;
h64 = h64*PRIME64_1 + PRIME64_4;
v2 *= PRIME64_2;
v2 = XXH_rotl64(v2, 31);
v2 *= PRIME64_1;
h64 ^= v2;
h64 = h64*PRIME64_1 + PRIME64_4;
v3 *= PRIME64_2;
v3 = XXH_rotl64(v3, 31);
v3 *= PRIME64_1;
h64 ^= v3;
h64 = h64*PRIME64_1 + PRIME64_4;
v4 *= PRIME64_2;
v4 = XXH_rotl64(v4, 31);
v4 *= PRIME64_1;
h64 ^= v4;
h64 = h64*PRIME64_1 + PRIME64_4;
}
else
{
h64 = state->seed + PRIME64_5;
}
h64 += (U64) state->total_len;
while (p+8<=bEnd)
{
U64 k1 = XXH_readLE64(p, endian);
k1 *= PRIME64_2;
k1 = XXH_rotl64(k1,31);
k1 *= PRIME64_1;
h64 ^= k1;
h64 = XXH_rotl64(h64,27) * PRIME64_1 + PRIME64_4;
p+=8;
}
if (p+4<=bEnd)
{
h64 ^= (U64)(XXH_readLE32(p, endian)) * PRIME64_1;
h64 = XXH_rotl64(h64, 23) * PRIME64_2 + PRIME64_3;
p+=4;
}
while (p<bEnd)
{
h64 ^= (*p) * PRIME64_5;
h64 = XXH_rotl64(h64, 11) * PRIME64_1;
p++;
}
h64 ^= h64 >> 33;
h64 *= PRIME64_2;
h64 ^= h64 >> 29;
h64 *= PRIME64_3;
h64 ^= h64 >> 32;
return h64;
}
unsigned long long XXH64_digest (const XXH64_state_t* state_in)
{
XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
return XXH64_digest_endian(state_in, XXH_littleEndian);
else
return XXH64_digest_endian(state_in, XXH_bigEndian);
}
} // detail
} // beast

View File

@@ -0,0 +1,154 @@
/*
xxHash - Extremely Fast Hash algorithm
Header File
Copyright (C) 2012-2014, Yann Collet.
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
You can contact the author at :
- xxHash source repository : http://code.google.com/p/xxhash/
*/
/* Notice extracted from xxHash homepage :
xxHash is an extremely fast Hash algorithm, running at RAM speed limits.
It also successfully passes all tests from the SMHasher suite.
Comparison (single thread, Windows Seven 32 bits, using SMHasher on a Core 2 Duo @3GHz)
Name Speed Q.Score Author
xxHash 5.4 GB/s 10
CrapWow 3.2 GB/s 2 Andrew
MumurHash 3a 2.7 GB/s 10 Austin Appleby
SpookyHash 2.0 GB/s 10 Bob Jenkins
SBox 1.4 GB/s 9 Bret Mulvey
Lookup3 1.2 GB/s 9 Bob Jenkins
SuperFastHash 1.2 GB/s 1 Paul Hsieh
CityHash64 1.05 GB/s 10 Pike & Alakuijala
FNV 0.55 GB/s 5 Fowler, Noll, Vo
CRC32 0.43 GB/s 9
MD5-32 0.33 GB/s 10 Ronald L. Rivest
SHA1-32 0.28 GB/s 10
Q.Score is a measure of quality of the hash function.
It depends on successfully passing SMHasher test set.
10 is a perfect score.
*/
#ifndef BEAST_HASH_XXHASH_H_INCLUDED
#define BEAST_HASH_XXHASH_H_INCLUDED
/*****************************
Includes
*****************************/
#include <stddef.h> /* size_t */
namespace beast {
namespace detail {
/*****************************
Type
*****************************/
typedef enum { XXH_OK=0, XXH_ERROR } XXH_errorcode;
/*****************************
Simple Hash Functions
*****************************/
unsigned int XXH32 (const void* input, size_t length, unsigned seed);
unsigned long long XXH64 (const void* input, size_t length, unsigned long long seed);
/*
XXH32() :
Calculate the 32-bits hash of sequence "length" bytes stored at memory address "input".
The memory between input & input+length must be valid (allocated and read-accessible).
"seed" can be used to alter the result predictably.
This function successfully passes all SMHasher tests.
Speed on Core 2 Duo @ 3 GHz (single thread, SMHasher benchmark) : 5.4 GB/s
XXH64() :
Calculate the 64-bits hash of sequence of length "len" stored at memory address "input".
*/
/*****************************
Advanced Hash Functions
*****************************/
typedef struct { long long ll[ 6]; } XXH32_state_t;
typedef struct { long long ll[11]; } XXH64_state_t;
/*
These structures allow static allocation of XXH states.
States must then be initialized using XXHnn_reset() before first use.
If you prefer dynamic allocation, please refer to functions below.
*/
XXH32_state_t* XXH32_createState(void);
XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr);
XXH64_state_t* XXH64_createState(void);
XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr);
/*
These functions create and release memory for XXH state.
States must then be initialized using XXHnn_reset() before first use.
*/
XXH_errorcode XXH32_reset (XXH32_state_t* statePtr, unsigned seed);
XXH_errorcode XXH32_update (XXH32_state_t* statePtr, const void* input, size_t length);
unsigned int XXH32_digest (const XXH32_state_t* statePtr);
XXH_errorcode XXH64_reset (XXH64_state_t* statePtr, unsigned long long seed);
XXH_errorcode XXH64_update (XXH64_state_t* statePtr, const void* input, size_t length);
unsigned long long XXH64_digest (const XXH64_state_t* statePtr);
/*
These functions calculate the xxHash of an input provided in multiple smaller packets,
as opposed to an input provided as a single block.
XXH state space must first be allocated, using either static or dynamic method provided above.
Start a new hash by initializing state with a seed, using XXHnn_reset().
Then, feed the hash state by calling XXHnn_update() as many times as necessary.
Obviously, input must be valid, meaning allocated and read accessible.
The function returns an error code, with 0 meaning OK, and any other value meaning there is an error.
Finally, you can produce a hash anytime, by using XXHnn_digest().
This function returns the final nn-bits hash.
You can nonetheless continue feeding the hash state with more input,
and therefore get some new hashes, by calling again XXHnn_digest().
When you are done, don't forget to free XXH state space, using typically XXHnn_freeState().
*/
} // detail
} // beast
#endif

View File

@@ -0,0 +1,59 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2014, Howard Hinnant <howard.hinnant@gmail.com>,
Vinnie Falco <vinnie.falco@gmail.com
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 BEAST_HASH_SIPHASH_H_INCLUDED
#define BEAST_HASH_SIPHASH_H_INCLUDED
#include <beast/utility/noexcept.h>
#include <cstddef>
#include <cstdint>
namespace beast {
// See https://131002.net/siphash/
class siphash
{
private:
std::uint64_t v0_ = 0x736f6d6570736575ULL;
std::uint64_t v1_ = 0x646f72616e646f6dULL;
std::uint64_t v2_ = 0x6c7967656e657261ULL;
std::uint64_t v3_ = 0x7465646279746573ULL;
unsigned char buf_[8];
unsigned bufsize_ = 0;
unsigned total_length_ = 0;
public:
using result_type = std::size_t;
siphash() = default;
explicit
siphash (std::uint64_t k0, std::uint64_t k1 = 0) noexcept;
void
append (void const* key, std::size_t len) noexcept;
explicit
operator std::size_t() noexcept;
};
} // beast
#endif

View File

@@ -1,7 +1,8 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Copyright 2014, Howard Hinnant <howard.hinnant@gmail.com>,
Vinnie Falco <vinnie.falco@gmail.com
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
@@ -17,30 +18,42 @@
*/
//==============================================================================
#ifndef BEAST_SQLITE_H_INCLUDED
#define BEAST_SQLITE_H_INCLUDED
#ifndef BEAST_HASH_SPOOKY_H_INCLUDED
#define BEAST_HASH_SPOOKY_H_INCLUDED
/** A self-contained, serverless, zero configuration, transactional SQL engine.
#include <beast/hash/impl/spookyv2.h>
This external module provides the SQLite embedded database library.
namespace beast {
SQLite is public domain software, visit http://sqlite.org
*/
// See http://burtleburtle.net/bob/hash/spooky.html
class spooky
{
private:
SpookyHash state_;
#include <beast/config/PlatformConfig.h>
public:
using result_type = std::size_t;
#if BEAST_IOS || BEAST_MAC
# define BEAST_HAVE_NATIVE_SQLITE 1
#else
# define BEAST_HAVE_NATIVE_SQLITE 0
#endif
spooky (std::size_t seed1 = 1, std::size_t seed2 = 2) noexcept
{
state_.Init (seed1, seed2);
}
#ifndef BEAST_SQLITE_CPP_INCLUDED
# if BEAST_USE_NATIVE_SQLITE && BEAST_HAVE_NATIVE_SQLITE
#include <sqlite3.h>
# else
#include <beast/module/sqlite/sqlite/sqlite3.h> // Amalgamated
# endif
#endif
void
append (void const* key, std::size_t len) noexcept
{
state_.Update (key, len);
}
explicit
operator std::size_t() noexcept
{
std::uint64_t h1, h2;
state_.Final (&h1, &h2);
return static_cast <std::size_t> (h1);
}
};
} // beast
#endif

View File

@@ -17,21 +17,15 @@
*/
//==============================================================================
// MODULES: ../impl/spookyv2.cpp
#if BEAST_INCLUDE_BEASTCONFIG
#include <BeastConfig.h>
#endif
#include <beast/container/tests/hash_metrics.h>
#include <beast/container/hash_append.h>
#include <beast/container/impl/spookyv2.h>
#include <beast/hash/tests/hash_metrics.h>
#include <beast/hash/hash_append.h>
#include <beast/chrono/chrono_io.h>
#include <beast/unit_test/suite.h>
#include <beast/utility/type_name.h>
#include <array>
#include <algorithm>
#include <cstring>
@@ -40,8 +34,6 @@
namespace beast {
//------------------------------------------------------------------------------
template <class Block, class Derived>
class block_stream
{

View File

@@ -18,8 +18,8 @@
*/
//==============================================================================
#ifndef BEAST_CONTAINER_TESTS_HASH_METRICS_H_INCLUDED
#define BEAST_CONTAINER_TESTS_HASH_METRICS_H_INCLUDED
#ifndef BEAST_HASH_HASH_METRICS_H_INCLUDED
#define BEAST_HASH_HASH_METRICS_H_INCLUDED
#include <algorithm>
#include <cmath>

View File

@@ -0,0 +1,86 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
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.
*/
//==============================================================================
#if BEAST_INCLUDE_BEASTCONFIG
#include <BeastConfig.h>
#endif
#include <beast/hash/fnv1a.h>
#include <beast/hash/siphash.h>
#include <beast/hash/xxhasher.h>
#include <beast/chrono/chrono_io.h>
#include <beast/random/rngfill.h>
#include <beast/random/xor_shift_engine.h>
#include <beast/unit_test/suite.h>
#include <array>
#include <chrono>
#include <cstdint>
#include <cstring>
#include <iomanip>
#include <random>
namespace beast {
class hash_speed_test : public beast::unit_test::suite
{
public:
using clock_type =
std::chrono::high_resolution_clock;
template <class Hasher, std::size_t KeySize>
void
test (std::string const& what, std::size_t n)
{
using namespace std;
using namespace std::chrono;
xor_shift_engine g(1);
array<std::uint8_t, KeySize> key;
auto const start = clock_type::now();
while(n--)
{
rngfill (key, g);
Hasher h;
h.append(key.data(), KeySize);
volatile size_t temp =
static_cast<std::size_t>(h);
(void)temp;
}
auto const elapsed = clock_type::now() - start;
log << setw(12) << what << " " <<
duration<double>(elapsed) << "s";
}
void
run()
{
enum
{
N = 100000000
};
#if ! BEAST_NO_XXHASH
test<xxhasher,32> ("xxhash", N);
#endif
test<fnv1a,32> ("fnv1a", N);
test<siphash,32> ("siphash", N);
pass();
}
};
BEAST_DEFINE_TESTSUITE_MANUAL(hash_speed,container,beast);
} // beast

View File

@@ -0,0 +1,46 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2014, Howard Hinnant <howard.hinnant@gmail.com>,
Vinnie Falco <vinnie.falco@gmail.com
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 BEAST_HASH_UHASH_H_INCLUDED
#define BEAST_HASH_UHASH_H_INCLUDED
#include <beast/hash/spooky.h>
namespace beast {
// Universal hash function
template <class Hasher = spooky>
struct uhash
{
using result_type = typename Hasher::result_type;
template <class T>
result_type
operator()(T const& t) const noexcept
{
Hasher h;
hash_append (h, t);
return static_cast<result_type>(h);
}
};
} // beast
#endif

View File

@@ -0,0 +1,86 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2014, Vinnie Falco <vinnie.falco@gmail.com>
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 BEAST_HASH_XXHASHER_H_INCLUDED
#define BEAST_HASH_XXHASHER_H_INCLUDED
#ifndef BEAST_NO_XXHASH
#define BEAST_NO_XXHASH 0
#endif
#if ! BEAST_NO_XXHASH
#include <beast/hash/impl/xxhash.h>
#include <beast/utility/noexcept.h>
#include <beast/cxx14/type_traits.h> // <type_traits>
#include <cstddef>
namespace beast {
class xxhasher
{
private:
// requires 64-bit std::size_t
static_assert(sizeof(std::size_t)==8, "");
detail::XXH64_state_t state_;
public:
using result_type = std::size_t;
xxhasher() noexcept
{
detail::XXH64_reset (&state_, 1);
}
template <class Seed,
std::enable_if_t<
std::is_unsigned<Seed>::value>* = nullptr>
explicit
xxhasher (Seed seed)
{
detail::XXH64_reset (&state_, seed);
}
template <class Seed,
std::enable_if_t<
std::is_unsigned<Seed>::value>* = nullptr>
xxhasher (Seed seed, Seed)
{
detail::XXH64_reset (&state_, seed);
}
void
append (void const* key, std::size_t len) noexcept
{
detail::XXH64_update (&state_, key, len);
}
explicit
operator std::size_t() noexcept
{
return detail::XXH64_digest(&state_);
}
};
} // beast
#endif
#endif

View File

@@ -27,6 +27,7 @@
#include <beast/http/impl/raw_parser.cpp>
#include <beast/http/impl/URL.cpp>
#include <beast/http/tests/chunked_encoder.test.cpp>
#include <beast/http/tests/parser.test.cpp>
#include <beast/http/tests/rfc2616.test.cpp>
#include <beast/http/tests/URL.test.cpp>

View File

@@ -50,17 +50,16 @@ public:
body (body const&) = delete;
body& operator= (body const&) = delete;
template <class = void>
void
clear();
void
write (void const* data, std::size_t bytes);
template <class ConstBufferSequence>
void
write (ConstBufferSequence const& buffers)
{
for (auto const& buffer : buffers)
write (boost::asio::buffer_cast <void const*> (buffer),
boost::asio::buffer_size (buffer));
}
write (ConstBufferSequence const& buffers);
std::size_t
size() const;
@@ -92,8 +91,9 @@ body::body()
inline
body::body (body&& other)
: buf_ (std::move(other.buf_))
{
buf_ = std::move(other.buf_);
other.clear();
}
inline
@@ -101,9 +101,17 @@ body&
body::operator= (body&& other)
{
buf_ = std::move(other.buf_);
other.clear();
return *this;
}
template <class>
void
body::clear()
{
buf_ = std::make_unique <buffer_type>();
}
inline
void
body::write (void const* data, std::size_t bytes)
@@ -112,6 +120,15 @@ body::write (void const* data, std::size_t bytes)
boost::asio::const_buffers_1 (data, bytes)));
}
template <class ConstBufferSequence>
void
body::write (ConstBufferSequence const& buffers)
{
for (auto const& buffer : buffers)
write (boost::asio::buffer_cast <void const*> (buffer),
boost::asio::buffer_size (buffer));
}
inline
std::size_t
body::size() const

View File

@@ -0,0 +1,285 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
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 BEAST_HTTP_CHUNK_ENCODE_H_INCLUDED
#define BEAST_HTTP_CHUNK_ENCODE_H_INCLUDED
#include <boost/asio/buffer.hpp>
#include <algorithm>
#include <array>
#include <cassert>
#include <cstddef>
#include <iterator>
#include <beast/cxx14/type_traits.h> // <type_traits>
namespace beast {
namespace http {
namespace detail {
template <class Buffers>
class chunk_encoded_buffers
{
private:
using const_buffer = boost::asio::const_buffer;
Buffers buffers_;
const_buffer head_;
const_buffer tail_;
// Storage for the longest hex string we might need, plus delimiters.
std::array<char, 2 * sizeof(std::size_t) + 2> data_;
public:
using value_type = boost::asio::const_buffer;
class const_iterator;
chunk_encoded_buffers() = delete;
chunk_encoded_buffers (chunk_encoded_buffers const&) = default;
chunk_encoded_buffers& operator= (chunk_encoded_buffers const&) = default;
chunk_encoded_buffers (Buffers const& buffers, bool final_chunk);
const_iterator
begin() const
{
return const_iterator(*this, false);
}
const_iterator
end() const
{
return const_iterator(*this, true);
}
private:
// Unchecked conversion of unsigned to hex string
template<class OutIter, class Unsigned>
static
std::enable_if_t<std::is_unsigned<Unsigned>::value, OutIter>
to_hex(OutIter const first, OutIter const last, Unsigned n);
};
template <class Buffers>
class chunk_encoded_buffers<Buffers>::const_iterator
: public std::iterator<std::bidirectional_iterator_tag, const_buffer>
{
private:
using iterator = typename Buffers::const_iterator;
enum class Where { head, input, end };
chunk_encoded_buffers const* buffers_;
Where where_;
iterator iter_;
public:
const_iterator();
const_iterator (const_iterator const&) = default;
const_iterator& operator= (const_iterator const&) = default;
bool operator== (const_iterator const& other) const;
bool operator!= (const_iterator const& other) const;
const_iterator& operator++();
const_iterator& operator--();
const_iterator operator++(int) const;
const_iterator operator--(int) const;
const_buffer operator*() const;
private:
friend class chunk_encoded_buffers;
const_iterator(chunk_encoded_buffers const& buffers, bool past_the_end);
};
//------------------------------------------------------------------------------
template <class Buffers>
chunk_encoded_buffers<Buffers>::chunk_encoded_buffers (
Buffers const& buffers, bool final_chunk)
: buffers_(buffers)
{
auto const size = boost::asio::buffer_size(buffers);
data_[data_.size() - 2] = '\r';
data_[data_.size() - 1] = '\n';
auto pos = to_hex(data_.begin(), data_.end() - 2, size);
head_ = const_buffer(&*pos,
std::distance(pos, data_.end()));
if (size > 0 && final_chunk)
tail_ = const_buffer("\r\n0\r\n\r\n", 7);
else
tail_ = const_buffer("\r\n", 2);
}
template <class Buffers>
template <class OutIter, class Unsigned>
std::enable_if_t<std::is_unsigned<Unsigned>::value, OutIter>
chunk_encoded_buffers<Buffers>::to_hex(
OutIter const first, OutIter const last, Unsigned n)
{
assert(first != last);
OutIter iter = last;
if(n == 0)
{
*--iter = '0';
return iter;
}
while(n)
{
assert(iter != first);
*--iter = "0123456789abcdef"[n&0xf];
n>>=4;
}
return iter;
}
template <class Buffers>
chunk_encoded_buffers<Buffers>::const_iterator::const_iterator()
: where_(Where::end)
, buffers_(nullptr)
{
}
template <class Buffers>
bool
chunk_encoded_buffers<Buffers>::const_iterator::operator==(
const_iterator const& other) const
{
return buffers_ == other.buffers_ &&
where_ == other.where_ && iter_ == other.iter_;
}
template <class Buffers>
bool
chunk_encoded_buffers<Buffers>::const_iterator::operator!=(
const_iterator const& other) const
{
return buffers_ != other.buffers_ ||
where_ != other.where_ || iter_ != other.iter_;
}
template <class Buffers>
auto
chunk_encoded_buffers<Buffers>::const_iterator::operator++() ->
const_iterator&
{
assert(buffers_);
assert(where_ != Where::end);
if (where_ == Where::head)
where_ = Where::input;
else if (iter_ != buffers_->buffers_.end())
++iter_;
else
where_ = Where::end;
return *this;
}
template <class Buffers>
auto
chunk_encoded_buffers<Buffers>::const_iterator::operator--() ->
const_iterator&
{
assert(buffers_);
assert(where_ != Where::begin);
if (where_ == Where::end)
where_ = Where::input;
else if (iter_ != buffers_->buffers_.begin())
--iter_;
else
where_ = Where::head;
return *this;
}
template <class Buffers>
auto
chunk_encoded_buffers<Buffers>::const_iterator::operator++(int) const ->
const_iterator
{
auto iter = *this;
++iter;
return iter;
}
template <class Buffers>
auto
chunk_encoded_buffers<Buffers>::const_iterator::operator--(int) const ->
const_iterator
{
auto iter = *this;
--iter;
return iter;
}
template <class Buffers>
auto
chunk_encoded_buffers<Buffers>::const_iterator::operator*() const ->
const_buffer
{
assert(buffers_);
assert(where_ != Where::end);
if (where_ == Where::head)
return buffers_->head_;
if (iter_ != buffers_->buffers_.end())
return *iter_;
return buffers_->tail_;
}
template <class Buffers>
chunk_encoded_buffers<Buffers>::const_iterator::const_iterator(
chunk_encoded_buffers const& buffers, bool past_the_end)
: buffers_(&buffers)
, where_(past_the_end ? Where::end : Where::head)
, iter_(past_the_end ? buffers_->buffers_.end() :
buffers_->buffers_.begin())
{
}
}
/** Returns a chunk-encoded BufferSequence.
See:
http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.6.1
@tparam Buffers A type meeting the requirements of BufferSequence.
@param buffers The input buffer sequence.
@param final_chunk `true` If this should include a final-chunk.
@return A chunk-encoded ConstBufferSeqeunce representing the input.
*/
/** @{ */
template <class Buffers>
detail::chunk_encoded_buffers<Buffers>
chunk_encode (Buffers const& buffers,
bool final_chunk = false)
{
return detail::chunk_encoded_buffers<
Buffers>(buffers, final_chunk);
}
// Returns a chunked encoding final chunk.
inline
boost::asio::const_buffers_1
chunk_encode_final()
{
return boost::asio::const_buffers_1(
"0\r\n\r\n", 5);
}
/** @} */
} // http
} // beast
#endif

View File

@@ -17,8 +17,8 @@
*/
//==============================================================================
#ifndef BEAST_HTTP_HEADER_TRAITS_H_INCLUDED
#define BEAST_HTTP_HEADER_TRAITS_H_INCLUDED
#ifndef BEAST_HTTP_DETAIL_HEADER_TRAITS_H_INCLUDED
#define BEAST_HTTP_DETAIL_HEADER_TRAITS_H_INCLUDED
#include <beast/utility/ci_char_traits.h>

View File

@@ -38,11 +38,7 @@ namespace http {
class headers
{
public:
struct value_type
{
std::string field;
std::string value;
};
using value_type = std::pair<std::string, std::string>;
private:
struct element
@@ -139,6 +135,13 @@ public:
void
clear() noexcept;
/** Remove a field.
@return The number of fields removed.
*/
template <class = void>
std::size_t
erase (std::string const& field);
/** Append a field value.
If a field value already exists the new value will be
extended as per RFC2616 Section 4.2.
@@ -164,8 +167,8 @@ template <class>
headers::element::element (
std::string const& f, std::string const& v)
{
data.field = f;
data.value = v;
data.first = f;
data.second = v;
}
template <class String>
@@ -173,7 +176,7 @@ bool
headers::less::operator() (
String const& lhs, element const& rhs) const
{
return beast::ci_less::operator() (lhs, rhs.data.field);
return beast::ci_less::operator() (lhs, rhs.data.first);
}
template <class String>
@@ -181,7 +184,7 @@ bool
headers::less::operator() (
element const& lhs, String const& rhs) const
{
return beast::ci_less::operator() (lhs.data.field, rhs);
return beast::ci_less::operator() (lhs.data.first, rhs);
}
//------------------------------------------------------------------------------
@@ -210,7 +213,7 @@ inline
headers::headers (headers const& other)
{
for (auto const& e : other.list_)
append (e.data.field, e.data.value);
append (e.data.first, e.data.second);
}
inline
@@ -219,7 +222,7 @@ headers::operator= (headers const& other)
{
clear();
for (auto const& e : other.list_)
append (e.data.field, e.data.value);
append (e.data.first, e.data.second);
return *this;
}
@@ -269,7 +272,7 @@ headers::operator[] (std::string const& field) const
auto const found (find (field));
if (found == end())
return none;
return found->value;
return found->second;
}
template <class>
@@ -280,6 +283,20 @@ headers::clear() noexcept
delete &(*iter++);
}
template <class>
std::size_t
headers::erase (std::string const& field)
{
auto const iter = set_.find(field, less{});
if (iter == set_.end())
return 0;
element& e = *iter;
set_.erase(set_.iterator_to(e));
list_.erase(list_.iterator_to(e));
delete &e;
return 1;
}
template <class>
void
headers::append (std::string const& field,
@@ -296,7 +313,7 @@ headers::append (std::string const& field,
}
// If field already exists, append comma
// separated value as per RFC2616 section 4.2
auto& cur (result.first->data.value);
auto& cur (result.first->data.second);
cur.reserve (cur.size() + 1 + value.size());
cur.append (1, ',');
cur.append (value);
@@ -304,6 +321,36 @@ headers::append (std::string const& field,
//------------------------------------------------------------------------------
template <class Streambuf>
void
write (Streambuf& stream, std::string const& s)
{
stream.commit (boost::asio::buffer_copy (
stream.prepare (s.size()), boost::asio::buffer(s)));
}
template <class Streambuf>
void
write (Streambuf& stream, char const* s)
{
auto const len (::strlen(s));
stream.commit (boost::asio::buffer_copy (
stream.prepare (len), boost::asio::buffer (s, len)));
}
template <class Streambuf>
void
write (Streambuf& stream, headers const& h)
{
for (auto const& _ : h)
{
write (stream, _.first);
write (stream, ": ");
write (stream, _.second);
write (stream, "\r\n");
}
}
template <class>
std::string
to_string (headers const& h)
@@ -311,13 +358,13 @@ to_string (headers const& h)
std::string s;
std::size_t n (0);
for (auto const& e : h)
n += e.field.size() + 2 + e.value.size() + 2;
n += e.first.size() + 2 + e.second.size() + 2;
s.reserve (n);
for (auto const& e : h)
{
s.append (e.field);
s.append (e.first);
s.append (": ");
s.append (e.value);
s.append (e.second);
s.append ("\r\n");
}
return s;
@@ -338,10 +385,10 @@ build_map (headers const& h)
std::map <std::string, std::string> c;
for (auto const& e : h)
{
auto key (e.field);
auto key (e.first);
// TODO Replace with safe C++14 version
std::transform (key.begin(), key.end(), key.begin(), ::tolower);
c [key] = e.value;
c [key] = e.second;
}
return c;
}

View File

@@ -18,8 +18,9 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#ifndef http_parser_h
#define http_parser_h
#ifndef BEAST_HTTP_HTTP_PARSER_HTTP_PARSER_H_INCLUDED
#define BEAST_HTTP_HTTP_PARSER_HTTP_PARSER_H_INCLUDED
#ifdef __cplusplus
extern "C" {
#endif
@@ -134,7 +135,7 @@ enum flags
/* Map for errno-related constants
*
*
* The provided argument should be a macro that takes 2 arguments.
*/
#define HTTP_ERRNO_MAP(XX) \

View File

@@ -21,7 +21,6 @@
#define BEAST_HTTP_MESSAGE_H_INCLUDED
#include <beast/http/basic_parser.h>
#include <beast/http/body.h>
#include <beast/http/method.h>
#include <beast/http/headers.h>
#include <beast/utility/ci_char_traits.h>
@@ -31,11 +30,26 @@
#include <cctype>
#include <ostream>
#include <string>
#include <sstream>
#include <utility>
namespace beast {
namespace http {
inline
std::pair<int, int>
http_1_0()
{
return std::pair<int, int>(1, 0);
}
inline
std::pair<int, int>
http_1_1()
{
return std::pair<int, int>(1, 1);
}
class message
{
private:
@@ -72,9 +86,8 @@ public:
#endif
// Memberspaces
// Memberspace
beast::http::headers headers;
beast::http::body body;
bool
request() const
@@ -180,6 +193,12 @@ public:
version_ = std::make_pair (major, minor);
}
void
version (std::pair<int, int> p)
{
version_ = p;
}
std::pair<int, int>
version() const
{
@@ -213,7 +232,6 @@ message::message (message&& other)
, keep_alive_ (other.keep_alive_)
, upgrade_ (other.upgrade_)
, headers (std::move(other.headers))
, body (std::move(other.body))
{
}
@@ -230,33 +248,15 @@ message::operator= (message&& other)
keep_alive_ = other.keep_alive_;
upgrade_ = other.upgrade_;
headers = std::move(other.headers);
body = std::move(other.body);
return *this;
}
#endif
//------------------------------------------------------------------------------
template <class AsioStreamBuf>
template <class Streambuf>
void
write (AsioStreamBuf& stream, std::string const& s)
{
stream.commit (boost::asio::buffer_copy (
stream.prepare (s.size()), boost::asio::buffer(s)));
}
template <class AsioStreamBuf>
void
write (AsioStreamBuf& stream, char const* s)
{
auto const len (::strlen(s));
stream.commit (boost::asio::buffer_copy (
stream.prepare (len), boost::asio::buffer (s, len)));
}
template <class AsioStreamBuf>
void
write (AsioStreamBuf& stream, message const& m)
write (Streambuf& stream, message const& m)
{
if (m.request())
{
@@ -280,13 +280,7 @@ write (AsioStreamBuf& stream, message const& m)
write (stream, m.reason());
}
write (stream, "\r\n");
for (auto const& header : m.headers)
{
write (stream, header.field);
write (stream, ": ");
write (stream, header.value);
write (stream, "\r\n");
}
write(stream, m.headers);
write (stream, "\r\n");
}
@@ -311,4 +305,4 @@ to_string (message const& m)
} // http
} // beast
#endif
#endif

View File

@@ -21,6 +21,8 @@
#define BEAST_HTTP_PARSER_H_INCLUDED
#include <beast/http/message.h>
#include <beast/http/body.h>
#include <functional>
#include <string>
#include <utility>
@@ -34,15 +36,33 @@ class parser : public beast::http::basic_parser
{
private:
std::reference_wrapper <message> message_;
std::function<void(void const*, std::size_t)> write_body_;
public:
/** Construct a parser for HTTP request or response.
The result is stored in the passed message.
The headers plus request or status line are stored in message.
The content-body, if any, is passed as a series of calls to
the write_body function. Transfer encodings are applied before
any data is passed to the write_body function.
*/
parser (message& m, bool request)
parser (std::function<void(void const*, std::size_t)> write_body,
message& m, bool request)
: beast::http::basic_parser (request)
, message_(m)
, write_body_(std::move(write_body))
{
message_.get().request(request);
}
parser (message& m, body& b, bool request)
: beast::http::basic_parser (request)
, message_(m)
{
write_body_ = [&b](void const* data, std::size_t size)
{
b.write(data, size);
};
message_.get().request(request);
}
@@ -135,7 +155,7 @@ parser::operator= (parser&& other)
template <class>
void
parser::do_start ()
parser::do_start()
{
}
@@ -176,7 +196,7 @@ template <class>
void
parser::do_body (void const* data, std::size_t bytes)
{
message_.get().body.write (data, bytes);
write_body_(data, bytes);
}
template <class>

View File

@@ -20,12 +20,14 @@
#ifndef BEAST_HTTP_RFC2616_H_INCLUDED
#define BEAST_HTTP_RFC2616_H_INCLUDED
#include <boost/regex.hpp>
#include <algorithm>
#include <string>
#include <iterator>
#include <utility>
#include <vector>
namespace beast {
namespace http {
/** Routines for performing RFC2616 compliance.
RFC2616:
@@ -129,8 +131,8 @@ trim (String const& s)
{
using std::begin;
using std::end;
auto first (begin(s));
auto last (end(s));
auto first = begin(s);
auto last = end(s);
std::tie (first, last) = trim (first, last);
return { first, last };
}
@@ -154,21 +156,25 @@ trim (std::string const& s)
return trim <std::string> (s);
}
/** Call a functor for each comma delimited element.
Quotes and escape sequences will be parsed and converted appropriately.
Excess white space, commas, double quotes, and empty elements are not
passed to func.
/** Parse a character sequence of values separated by commas.
Double quotes and escape sequences will be converted. Excess white
space, commas, double quotes, and empty elements are not copied.
Format:
#(token|quoted-string)
Reference:
http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2
*/
template <class FwdIter, class Function>
void
for_each_element (FwdIter first, FwdIter last, Function func)
template <class FwdIt,
class Result = std::vector<
std::basic_string<typename FwdIt::value_type>>,
class Char>
Result
split(FwdIt first, FwdIt last, Char delim)
{
FwdIter iter (first);
std::string e;
Result result;
using string = typename Result::value_type;
FwdIt iter = first;
string e;
while (iter != last)
{
if (*iter == '"')
@@ -198,16 +204,16 @@ for_each_element (FwdIter first, FwdIter last, Function func)
}
if (! e.empty())
{
func (e);
result.emplace_back(std::move(e));
e.clear();
}
}
else if (*iter == ',')
else if (*iter == delim)
{
e = trim_right (e);
if (! e.empty())
{
func (e);
result.emplace_back(std::move(e));
e.clear();
}
++iter;
@@ -226,13 +232,29 @@ for_each_element (FwdIter first, FwdIter last, Function func)
{
e = trim_right (e);
if (! e.empty())
func (e);
result.emplace_back(std::move(e));
}
return result;
}
template <class FwdIt,
class Result = std::vector<
std::basic_string<typename FwdIt::value_type>>>
Result
split_commas(FwdIt first, FwdIt last)
{
return split(first, last, ',');
}
template <class Result = std::vector<std::string>>
Result
split_commas(std::string const& s)
{
return split_commas(s.begin(), s.end());
}
} // rfc2616
} // http
} // beast
#endif

View File

@@ -0,0 +1,151 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
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.
*/
//==============================================================================
#include <beast/asio/streambuf.h>
#include <beast/http/chunk_encode.h>
#include <beast/unit_test/suite.h>
namespace beast {
namespace http {
class chunk_encode_test : public unit_test::suite
{
public:
// Convert CR LF to printables for display
static
std::string
encode (std::string const& s)
{
std::string result;
for(auto const c : s)
{
if (c == '\r')
result += "\\r";
else if (c== '\n')
result += "\\n";
else
result += c;
}
return result;
}
// Print the contents of a ConstBufferSequence to the log
template <class ConstBufferSequence, class Log>
static
void
print (ConstBufferSequence const& buffers, Log log)
{
for(auto const& buf : buffers)
log << encode (std::string(
boost::asio::buffer_cast<char const*>(buf),
boost::asio::buffer_size(buf)));
}
// Convert a ConstBufferSequence to a string
template <class ConstBufferSequence>
static
std::string
buffer_to_string (ConstBufferSequence const& b)
{
std::string s;
auto const n = boost::asio::buffer_size(b);
s.resize(n);
boost::asio::buffer_copy(
boost::asio::buffer(&s[0], n), b);
return s;
}
// Append a ConstBufferSequence to an existing string
template <class ConstBufferSequence>
static
void
buffer_append (std::string& s, ConstBufferSequence const& b)
{
s += buffer_to_string(b);
}
// Convert the input sequence of the stream to a
// chunked-encoded string. The input sequence is consumed.
template <class Streambuf>
static
std::string
streambuf_to_string (Streambuf& sb,
bool final_chunk = false)
{
std::string s;
buffer_append(s, chunk_encode(sb.data(), final_chunk));
return s;
}
// Check an input against the correct chunk encoded version
void
check (std::string const& in, std::string const& answer,
bool final_chunk = true)
{
asio::streambuf sb(3);
sb << in;
auto const out = streambuf_to_string (sb, final_chunk);
if (! expect (out == answer))
log << "expected\n" << encode(answer) <<
"\ngot\n" << encode(out);
}
void testStreambuf()
{
asio::streambuf sb(3);
std::string const s =
"0123456789012345678901234567890123456789012345678901234567890123456789"
"0123456789012345678901234567890123456789012345678901234567890123456789"
"0123456789012345678901234567890123456789012345678901234567890123456789";
sb << s;
expect(buffer_to_string(sb.data()) == s);
}
void
testEncoder()
{
check("", "0\r\n\r\n");
check("x", "1\r\nx\r\n0\r\n\r\n");
check("abcd", "4\r\nabcd\r\n0\r\n\r\n");
check("x", "1\r\nx\r\n", false);
check(
"0123456789012345678901234567890123456789012345678901234567890123456789"
"0123456789012345678901234567890123456789012345678901234567890123456789"
"0123456789012345678901234567890123456789012345678901234567890123456789"
,
"d2\r\n"
"0123456789012345678901234567890123456789012345678901234567890123456789"
"0123456789012345678901234567890123456789012345678901234567890123456789"
"0123456789012345678901234567890123456789012345678901234567890123456789"
"\r\n"
"0\r\n\r\n");
}
void
run()
{
testStreambuf();
testEncoder();
}
};
BEAST_DEFINE_TESTSUITE(chunk_encode,http,beast);
}
}

View File

@@ -20,6 +20,7 @@
#include <beast/http/message.h>
#include <beast/http/parser.h>
#include <beast/unit_test/suite.h>
#include <utility>
namespace beast {
namespace http {
@@ -31,7 +32,8 @@ public:
request (std::string const& text)
{
message m;
parser p (m, true);
body b;
parser p (m, b, true);
auto result (p.write (boost::asio::buffer(text)));
p.write_eof();
return std::make_pair (std::move(m), result.first);
@@ -56,16 +58,27 @@ public:
log << "|" << result.first.headers["Field"] << "|";
}
void
test_headers()
{
headers h;
h.append("Field", "Value");
expect (h.erase("Field") == 1);
}
void
run()
{
test_headers();
{
std::string const text =
"GET / HTTP/1.1\r\n"
"\r\n"
;
message m;
parser p (m, true);
body b;
parser p (m, b, true);
auto result (p.write (boost::asio::buffer(text)));
expect (! result.first);
auto result2 (p.write_eof());
@@ -80,7 +93,8 @@ public:
"\r\n"
;
message m;
parser p (m, true);
body b;
parser p (m, b, true);
auto result = p.write (boost::asio::buffer(text));
if (expect (result.first))
expect (result.first.message() == "invalid HTTP method");

View File

@@ -27,62 +27,56 @@
#include <vector>
namespace beast {
namespace http {
namespace rfc2616 {
class rfc2616_test : public beast::unit_test::suite
{
public:
void
check (std::string const& value,
check (std::string const& s,
std::vector <std::string> const& expected)
{
std::vector <std::string> parsed;
for_each_element (value.begin(), value.end(),
[&](std::string const& element)
{
parsed.push_back (element);
});
auto const parsed = split_commas(s.begin(), s.end());
expect (parsed == expected);
}
void test_split_commas()
{
testcase("split_commas");
check ("", {});
check (" ", {});
check (" ", {});
check ("\t", {});
check (" \t ", {});
check (",", {});
check (",,", {});
check (" ,", {});
check (" , ,", {});
check ("x", {"x"});
check (" x", {"x"});
check (" \t x", {"x"});
check ("x ", {"x"});
check ("x \t", {"x"});
check (" \t x \t ", {"x"});
check ("\"\"", {});
check (" \"\"", {});
check ("\"\" ", {});
check ("\"x\"", {"x"});
check ("\" \"", {" "});
check ("\" x\"", {" x"});
check ("\"x \"", {"x "});
check ("\" x \"", {" x "});
check ("\"\tx \"", {"\tx "});
check ("x,y", { "x", "y" });
check ("x ,\ty ", { "x", "y" });
check ("x, y, z", {"x","y","z"});
check ("x, \"y\", z", {"x","y","z"});
}
void
run()
{
check ("", {});
check (" ", {});
check (" ", {});
check ("\t", {});
check (" \t ", {});
check (",", {});
check (",,", {});
check (" ,", {});
check (" , ,", {});
check ("x", {"x"});
check (" x", {"x"});
check (" \t x", {"x"});
check ("x ", {"x"});
check ("x \t", {"x"});
check (" \t x \t ", {"x"});
check ("\"\"", {});
check (" \"\"", {});
check ("\"\" ", {});
check ("\"x\"", {"x"});
check ("\" \"", {" "});
check ("\" x\"", {" x"});
check ("\"x \"", {"x "});
check ("\" x \"", {" x "});
check ("\"\tx \"", {"\tx "});
check ("x,y", { "x", "y" });
check ("x ,\ty ", { "x", "y" });
check ("x, y, z", {"x","y","z"});
check ("x, \"y\", z", {"x","y","z"});
test_split_commas();
}
};
@@ -90,4 +84,3 @@ BEAST_DEFINE_TESTSUITE(rfc2616,http,beast);
}
}
}

View File

@@ -18,8 +18,8 @@
//==============================================================================
#include <unordered_map>
#include <beast/cxx14/memory.h>
#include <beast/hash/uhash.h>
#include <beast/cxx14/memory.h> // <memory>
namespace beast {
namespace insight {

View File

@@ -322,7 +322,10 @@ public:
std::move (buffer))));
}
void on_send (boost::system::error_code ec, std::size_t)
// The keepAlive parameter makes sure the buffers sent to
// boost::asio::async_send do not go away until the call is finished
void on_send (std::shared_ptr<std::deque<std::string>> /*keepAlive*/,
boost::system::error_code ec, std::size_t)
{
if (ec == boost::asio::error::operation_aborted)
return;
@@ -354,6 +357,9 @@ public:
// Send what we have
void send_buffers ()
{
if (m_data.empty ())
return;
// Break up the array of strings into blocks
// that each fit into one UDP packet.
//
@@ -361,7 +367,12 @@ public:
std::vector <boost::asio::const_buffer> buffers;
buffers.reserve (m_data.size ());
std::size_t size (0);
for (auto const& s : m_data)
auto keepAlive =
std::make_shared<std::deque<std::string>>(std::move (m_data));
m_data.clear ();
for (auto const& s : *keepAlive)
{
std::size_t const length (s.size ());
assert (! s.empty ());
@@ -371,7 +382,7 @@ public:
log (buffers);
#endif
m_socket.async_send (buffers, std::bind (
&StatsDCollectorImp::on_send, this,
&StatsDCollectorImp::on_send, this, keepAlive,
beast::asio::placeholders::error,
beast::asio::placeholders::bytes_transferred));
buffers.clear ();
@@ -388,11 +399,10 @@ public:
log (buffers);
#endif
m_socket.async_send (buffers, std::bind (
&StatsDCollectorImp::on_send, this,
&StatsDCollectorImp::on_send, this, keepAlive,
beast::asio::placeholders::error,
beast::asio::placeholders::bytes_transferred));
}
m_data.clear ();
}
void set_timer ()

View File

@@ -17,8 +17,8 @@
*/
//==============================================================================
#ifndef BEAST_ASIO_ASYNCOBJECT_H_INCLUDED
#define BEAST_ASIO_ASYNCOBJECT_H_INCLUDED
#ifndef BEAST_MODULE_ASIO_ASYNCOBJECT_H_INCLUDED
#define BEAST_MODULE_ASIO_ASYNCOBJECT_H_INCLUDED
#include <atomic>
#include <cassert>
@@ -83,8 +83,8 @@ public:
void removeReference ()
{
if (--m_pending)
(static_cast <Derived *> (this))->asyncHandlersComplete ();
if (--m_pending == 0)
(static_cast<Derived*>(this))->asyncHandlersComplete();
}
private:

View File

@@ -17,8 +17,8 @@
*/
//==============================================================================
#ifndef BEAST_ASIO_SYSTEM_BOOSTINCLUDES_H_INCLUDED
#define BEAST_ASIO_SYSTEM_BOOSTINCLUDES_H_INCLUDED
#ifndef BEAST_MODULE_ASIO_BOOSTINCLUDES_H_INCLUDED
#define BEAST_MODULE_ASIO_BOOSTINCLUDES_H_INCLUDED
// Make sure we take care of fixing boost::bind oddities first.
#if !defined(BEAST_CORE_H_INCLUDED)

Some files were not shown because too many files have changed in this diff Show More