From 0996c57ac91f80b69373dc287469a56259a57e03 Mon Sep 17 00:00:00 2001 From: Damyan Ivanov Date: Thu, 4 Apr 2019 09:41:06 +0300 Subject: [PATCH] JSON transaction parser: detect file-order stream and disable the early termination logic the early termination logic is useful when transactions come in reverse chronological order -- newest first. seeing 50 known transactions seems like a good criteria for terminating the parsing before the whole stream is processed however, the JSON API seems to return transactions in file order -- oldest first (by time of creation, not 'date' field). in this order the newest (and thus unknown) transactions come last and the early termination logic needs to be disabled --- .../async/RetrieveTransactionsTask.java | 30 ++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/net/ktnx/mobileledger/async/RetrieveTransactionsTask.java b/app/src/main/java/net/ktnx/mobileledger/async/RetrieveTransactionsTask.java index 57a2739f..ea648c17 100644 --- a/app/src/main/java/net/ktnx/mobileledger/async/RetrieveTransactionsTask.java +++ b/app/src/main/java/net/ktnx/mobileledger/async/RetrieveTransactionsTask.java @@ -492,17 +492,42 @@ public class RetrieveTransactionsTask int processedTransactionCount = 0; + DetectedTransactionOrder transactionOrder = DetectedTransactionOrder.UNKNOWN; + int orderAccumulator = 0; + int lastTransactionId = 0; + while (true) { throwIfCancelled(); ParsedLedgerTransaction parsedTransaction = parser.nextTransaction(); throwIfCancelled(); if (parsedTransaction == null) break; + LedgerTransaction transaction = parsedTransaction.asLedgerTransaction(); + if (transaction.getId() > lastTransactionId) orderAccumulator++; + else orderAccumulator--; + lastTransactionId = transaction.getId(); + if (transactionOrder == DetectedTransactionOrder.UNKNOWN) { + if (orderAccumulator > 30) { + transactionOrder = DetectedTransactionOrder.FILE; + Log.d("rtt", String.format( + "Detected native file order after %d transactions (factor %d)", + processedTransactionCount, orderAccumulator)); + } + else if (orderAccumulator < -30) { + transactionOrder = DetectedTransactionOrder.REVERSE_CHRONOLOGICAL; + Log.d("rtt", String.format( + "Detected reverse chronological order after %d transactions (factor %d)", + processedTransactionCount, orderAccumulator)); + } + } + if (transaction.existsInDb(db)) { profile.markTransactionAsPresent(db, transaction); matchedTransactionsCount++; - if (matchedTransactionsCount == MATCHING_TRANSACTIONS_LIMIT) { + if ((transactionOrder == DetectedTransactionOrder.REVERSE_CHRONOLOGICAL) && + (matchedTransactionsCount == MATCHING_TRANSACTIONS_LIMIT)) + { profile.markTransactionsBeforeTransactionAsPresent(db, transaction); progress.setTotal(progress.getProgress()); publishProgress(progress); @@ -538,6 +563,8 @@ public class RetrieveTransactionsTask return true; } + + ; @SuppressLint("DefaultLocale") @Override protected String doInBackground(Void... params) { @@ -578,6 +605,7 @@ public class RetrieveTransactionsTask private void throwIfCancelled() { if (isCancelled()) throw new OperationCanceledException(null); } + enum DetectedTransactionOrder {UNKNOWN, REVERSE_CHRONOLOGICAL, FILE} private enum ParserState { EXPECTING_ACCOUNT, EXPECTING_ACCOUNT_AMOUNT, EXPECTING_JOURNAL, EXPECTING_TRANSACTION, -- 2.39.2