]> git.ktnx.net Git - mobile-ledger.git/commitdiff
JSON transaction parser: detect file-order stream and disable the early termination...
authorDamyan Ivanov <dam+mobileledger@ktnx.net>
Thu, 4 Apr 2019 06:41:06 +0000 (09:41 +0300)
committerDamyan Ivanov <dam+mobileledger@ktnx.net>
Thu, 4 Apr 2019 06:41:06 +0000 (09:41 +0300)
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

app/src/main/java/net/ktnx/mobileledger/async/RetrieveTransactionsTask.java

index 57a2739f70e066997907f6f1ed1935602b601540..ea648c17d3b376fb12edae9d9cd938688210e70a 100644 (file)
@@ -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,