Transaction: reimplement SORT_TX_BY_UPDATE_TIME and SORT_TX_BY_HEIGHT comparators in a functional way

This commit is contained in:
Andreas Schildbach 2023-03-10 16:40:47 +01:00
parent 95549b4754
commit 034277fae0

View file

@ -87,29 +87,34 @@ import static org.bitcoinj.base.internal.ByteUtils.uint64ToByteStreamLE;
* <p>Instances of this class are not safe for use by multiple threads.</p> * <p>Instances of this class are not safe for use by multiple threads.</p>
*/ */
public class Transaction extends ChildMessage { public class Transaction extends ChildMessage {
private static final Comparator<Transaction> SORT_TX_BY_ID = Comparator.comparing(Transaction::getTxId);
/** /**
* A comparator that can be used to sort transactions by their updateTime field. The ordering goes from most recent * A comparator that can be used to sort transactions by their updateTime field. The ordering goes from most recent
* into the past. * into the past.
*/ */
public static final Comparator<Transaction> SORT_TX_BY_UPDATE_TIME = (tx1, tx2) -> { public static final Comparator<Transaction> SORT_TX_BY_UPDATE_TIME = Comparator.comparing(
Instant t1 = tx1.getUpdateTimeInstant().orElse(Instant.EPOCH); Transaction::sortableUpdateTime,
Instant t2 = tx2.getUpdateTimeInstant().orElse(Instant.EPOCH); Comparator.reverseOrder())
final int updateTimeComparison = -(t1.compareTo(t2)); .thenComparing(SORT_TX_BY_ID);
//If time1==time2, compare by tx hash to make comparator consistent with equals private static Instant sortableUpdateTime(Transaction tx) {
return updateTimeComparison != 0 ? updateTimeComparison : tx1.getTxId().compareTo(tx2.getTxId()); return tx.getUpdateTimeInstant().orElse(Instant.EPOCH);
}; }
/** A comparator that can be used to sort transactions by their chain height. */
public static final Comparator<Transaction> SORT_TX_BY_HEIGHT = (tx1, tx2) -> { /**
final TransactionConfidence confidence1 = tx1.getConfidence(); * A comparator that can be used to sort transactions by their chain height.
final int height1 = confidence1.getConfidenceType() == ConfidenceType.BUILDING */
? confidence1.getAppearedAtChainHeight() : Block.BLOCK_HEIGHT_UNKNOWN; public static final Comparator<Transaction> SORT_TX_BY_HEIGHT = Comparator.comparing(
final TransactionConfidence confidence2 = tx2.getConfidence(); Transaction::sortableBlockHeight,
final int height2 = confidence2.getConfidenceType() == ConfidenceType.BUILDING Comparator.reverseOrder())
? confidence2.getAppearedAtChainHeight() : Block.BLOCK_HEIGHT_UNKNOWN; .thenComparing(SORT_TX_BY_ID);
final int heightComparison = -(Integer.compare(height1, height2)); private static int sortableBlockHeight(Transaction tx) {
//If height1==height2, compare by tx hash to make comparator consistent with equals TransactionConfidence confidence = tx.getConfidence();
return heightComparison != 0 ? heightComparison : tx1.getTxId().compareTo(tx2.getTxId()); return confidence.getConfidenceType() == ConfidenceType.BUILDING ?
}; confidence.getAppearedAtChainHeight() :
Block.BLOCK_HEIGHT_UNKNOWN;
}
private static final Logger log = LoggerFactory.getLogger(Transaction.class); private static final Logger log = LoggerFactory.getLogger(Transaction.class);
/** /**