This repository was archived by the owner on Aug 23, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 370
Feature: Improved CW Calculation #1451
Merged
+219
−211
Merged
Changes from 5 commits
Commits
Show all changes
22 commits
Select commit
Hold shift + click to select a range
a419063
added recursive weight calc
855ec6a
Added ignore to failed test and changed cum-weight test to recursive …
9951d39
Changed to queue
676eef4
Added some map optimizations and decreased db usage
2966d99
Implement recursive in codebase
ccd5536
Merge branch 'dev' into daf-cw
fbaf71d
Merge branch 'dev' into daf-cw
10e3f16
Removed backup cache
77fde23
Merge branch 'daf-cw' of https://github.com/kwek20/iri into daf-cw
ed951f1
Removed recursiveness
34ee23b
Merge branch 'dev' into daf-cw
4953955
Review comments
525d687
Merge branch 'dev' into daf-cw
dba6828
Merge branch 'daf-cw' of https://github.com/kwek20/iri into daf-cw
1ae6a80
Renamed and used Cum weight calc, added some javadoc, improved the al…
4d067a1
single depth search, removed hasAll
1b0aaff
Simplified check
29c40a0
Fixed circular -> self referencing
babc42f
Updated description
d410622
Removed link
dfa4599
Removed HashId need
3f5d176
Fixed Transformingmap usage in tests
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,22 +21,25 @@ | |
import com.iota.iri.utils.collections.interfaces.UnIterableMap; | ||
|
||
/** | ||
* Calculates the weight recursively/on the fly | ||
* Used to create a weighted random walks. | ||
* Implementation of {@link RatingCalculator} that calculates the cumulative weight | ||
* Calculates the weight recursively/on the fly for each transaction referencing {@code entryPoint}. <br> | ||
* Works using DFS search for new hashes and a BFS calculation. | ||
* Uses cached values to prevent double database lookup for approvers | ||
* | ||
* @see <a href="cumulative.md">https://github.com/alongalky/iota-docs/blob/master/cumulative.md</a> | ||
*/ | ||
public class RecursiveWeightCalculator implements RatingCalculator { | ||
public class CumulativeWeightCalculator implements RatingCalculator { | ||
|
||
private final Tangle tangle; | ||
private final SnapshotProvider snapshotProvider; | ||
|
||
/** | ||
* Constructor for Recursive Weight Calculator | ||
* Constructor for Cumulative Weight Calculator | ||
* | ||
* @param tangle Tangle object which acts as a database interface | ||
* @param snapshotProvider accesses ledger's snapshots | ||
*/ | ||
public RecursiveWeightCalculator(Tangle tangle, SnapshotProvider snapshotProvider) { | ||
public CumulativeWeightCalculator(Tangle tangle, SnapshotProvider snapshotProvider) { | ||
this.tangle = tangle; | ||
this.snapshotProvider = snapshotProvider; | ||
} | ||
|
@@ -55,40 +58,58 @@ private UnIterableMap<HashId, Integer> calculateRatingDfs(Hash entryPoint) throw | |
: 1; | ||
|
||
// Estimated capacity per depth, assumes 5 minute gap in between milestones, at 3tps | ||
UnIterableMap<HashId, Integer> hashWeight = createTxHashToCumulativeWeightMap( 5 * 60 * 3 * depth); | ||
UnIterableMap<HashId, Integer> hashWeightMap = createTxHashToCumulativeWeightMap( 5 * 60 * 3 * depth); | ||
|
||
Map<Hash, Set<Hash>> txToDirectApprovers = new HashMap<>(); | ||
|
||
Deque<Hash> stack = new ArrayDeque<>(); | ||
stack.push(entryPoint); | ||
stack.addAll(getTxDirectApproversHashes(entryPoint, txToDirectApprovers)); | ||
|
||
while (!stack.isEmpty()) { | ||
Hash txHash = stack.peekLast(); | ||
Hash txHash = stack.pollLast(); | ||
|
||
Set<Hash> approvers = getTxDirectApproversHashes(txHash, txToDirectApprovers); | ||
if (null != approvers && (approvers.size() == 0 || hasAll(hashWeight, approvers, stack))) { | ||
approvers.add(txHash); | ||
hashWeight.put(txHash, getRating(approvers, txToDirectApprovers)); | ||
stack.removeLast(); | ||
|
||
// If its empty, its a tip! | ||
if (approvers.isEmpty()) { | ||
hashWeightMap.put(txHash, 1); | ||
|
||
// Else we go deeper | ||
} else { | ||
stack.addAll(approvers); | ||
} | ||
// Add all approvers, given we didnt go there | ||
for (Hash h : approvers) { | ||
if (!hashWeightMap.containsKey(h)) { | ||
stack.add(h); | ||
} | ||
} | ||
|
||
// Add the tx to the approvers list to count itself as +1 weight, preventing self-referencing | ||
approvers.add(txHash); | ||
|
||
// calculate and add rating. Naturally the first time all approvers need to be looked up. Then its cached. | ||
hashWeightMap.put(txHash, getRating(approvers, txToDirectApprovers)); | ||
} | ||
} | ||
|
||
return hashWeight; | ||
// If we have a circular reference, its already added, otherwise we save a big calculation | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. circular -> self referencing |
||
if (!hashWeightMap.containsKey(entryPoint)) { | ||
hashWeightMap.put(entryPoint, hashWeightMap.size() + 1); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nice |
||
} | ||
return hashWeightMap; | ||
} | ||
|
||
/** | ||
* Gets the rating of a set, calculated by checking its approvers | ||
* | ||
* @param startingSet | ||
* @param txToDirectApproversCache | ||
* @return | ||
* @throws Exception | ||
* @param startingSet All approvers of a certain hash, including the hash itself. | ||
* Should always start with at least 1 hash. | ||
* @param txToDirectApproversCache The cache of approvers, used to prevent double db lookups | ||
* @return The weight, or rating, of the starting hash | ||
* @throws Exception If we can't get the approvers | ||
*/ | ||
private int getRating(Set<Hash> startingSet, Map<Hash, Set<Hash>> txToDirectApproversCache) throws Exception { | ||
Deque<Hash> stack = new ArrayDeque<>(startingSet); | ||
while (stack.isEmpty()) { | ||
while (!stack.isEmpty()) { | ||
Set<Hash> approvers = getTxDirectApproversHashes(stack.pollLast(), txToDirectApproversCache); | ||
for (Hash hash : approvers) { | ||
if (startingSet.add(hash)) { | ||
|
@@ -99,22 +120,6 @@ private int getRating(Set<Hash> startingSet, Map<Hash, Set<Hash>> txToDirectAppr | |
|
||
return startingSet.size(); | ||
} | ||
|
||
/** | ||
* | ||
* @param source | ||
* @param requester | ||
* @param stack | ||
* @return | ||
*/ | ||
private boolean hasAll(UnIterableMap<HashId, Integer> source, Set<Hash> requester, Deque<Hash> stack) { | ||
for (Hash h : requester) { | ||
if (!source.containsKey(h) && !stack.contains(h)) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
} | ||
|
||
/** | ||
* Finds the approvers of a transaction, and adds it to the txToDirectApprovers map if they weren't there yet. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,7 +18,6 @@ | |
import org.junit.AfterClass; | ||
import org.junit.Assert; | ||
import org.junit.BeforeClass; | ||
import org.junit.Ignore; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So we're still using transforming map Fine with that, we can change it later |
||
import org.junit.Test; | ||
import org.junit.rules.TemporaryFolder; | ||
import org.slf4j.Logger; | ||
|
@@ -65,7 +64,7 @@ public static void setUp() throws Exception { | |
tangle.addPersistenceProvider( new RocksDBPersistenceProvider( | ||
dbFolder.getRoot().getAbsolutePath(), logFolder.getRoot().getAbsolutePath(),1000, Tangle.COLUMN_FAMILIES, Tangle.METADATA_COLUMN_FAMILY)); | ||
tangle.init(); | ||
cumulativeWeightCalculator = new RecursiveWeightCalculator(tangle, snapshotProvider); | ||
cumulativeWeightCalculator = new CumulativeWeightCalculator(tangle, snapshotProvider); | ||
} | ||
|
||
@Test | ||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Delete this link