From ce150a560448657d91eb0883698ccdd62b8402a9 Mon Sep 17 00:00:00 2001
From: roadscape <roadscape@users.noreply.github.com>
Date: Mon, 5 Aug 2019 15:45:12 -0500
Subject: [PATCH] maintain accounts.rank field, close #144

---
 hive/indexer/accounts.py | 22 +++++++++++++---------
 hive/indexer/sync.py     |  7 ++++---
 2 files changed, 17 insertions(+), 12 deletions(-)

diff --git a/hive/indexer/accounts.py b/hive/indexer/accounts.py
index c885298f3..1736e5f58 100644
--- a/hive/indexer/accounts.py
+++ b/hive/indexer/accounts.py
@@ -26,6 +26,9 @@ class Accounts:
     # fifo queue
     _dirty = UniqueFIFO()
 
+    # in-mem id->rank map
+    _ranks = {}
+
     # account core methods
     # --------------------
 
@@ -116,15 +119,11 @@ class Accounts:
         return count
 
     @classmethod
-    def update_ranks(cls):
-        """Rebuild `hive_accounts` table rank-by-vote-weight column."""
-        sql = """
-        UPDATE hive_accounts
-           SET rank = r.rnk
-          FROM (SELECT id, ROW_NUMBER() OVER (ORDER BY vote_weight DESC) as rnk FROM hive_accounts) r
-         WHERE hive_accounts.id = r.id AND rank != r.rnk;
-        """
-        DB.query(sql)
+    def fetch_ranks(cls):
+        """Rebuild account ranks and store in memory for next update."""
+        sql = "SELECT id FROM hive_accounts ORDER BY vote_weight DESC"
+        for rank, _id in enumerate(DB.query_col(sql)):
+            cls._ranks[_id] = rank + 1
 
     @classmethod
     def _cache_accounts(cls, accounts, steem, trx=True):
@@ -186,5 +185,10 @@ class Accounts:
 
             'raw_json': json.dumps(account)}
 
+        # update rank field, if present
+        _id = cls.get_id(account['name'])
+        if _id in cls._ranks:
+            values['rank'] = cls._ranks[_id]
+
         bind = ', '.join([k+" = :"+k for k in list(values.keys())][1:])
         return ("UPDATE hive_accounts SET %s WHERE name = :name" % bind, values)
diff --git a/hive/indexer/sync.py b/hive/indexer/sync.py
index 38d155471..d87a3c93b 100644
--- a/hive/indexer/sync.py
+++ b/hive/indexer/sync.py
@@ -39,8 +39,9 @@ class Sync:
         # ensure db schema up to date, check app status
         DbState.initialize()
 
-        # prefetch id->name memory map
+        # prefetch id->name and id->rank memory maps
         Accounts.load_ids()
+        Accounts.fetch_ranks()
 
         if DbState.is_initial_sync():
             # resume initial sync
@@ -189,8 +190,8 @@ class Sync:
                      cnt['insert'], cnt['update'], cnt['payout'], cnt['upvote'],
                      cnt['recount'], accts, follows, ms, ' SLOW' if ms > 1000 else '')
 
-            #if num % 1200 == 0: #1hr
-            #    Accounts.update_ranks() #144
+            if num % 1200 == 0: #1hr
+                Accounts.fetch_ranks()
             if num % 100 == 0: #5min
                 Accounts.dirty_oldest(500)
                 Accounts.flush(steemd, trx=True)
-- 
GitLab