changeset 6bbc19a57553 in trytond:default
details: https://hg.tryton.org/trytond?cmd=changeset&node=6bbc19a57553
description:
        Add estimation count to ModelStorage

        issue10623
        review350381002
diffstat:

 CHANGELOG                     |   1 +
 doc/ref/models/models.rst     |   4 ++++
 doc/topics/configuration.rst  |  15 +++++++++++++++
 trytond/model/modelstorage.py |  32 +++++++++++++++++++++++++++++++-
 4 files changed, 51 insertions(+), 1 deletions(-)

diffs (130 lines):

diff -r 2be0f68b7ac5 -r 6bbc19a57553 CHANGELOG
--- a/CHANGELOG Sat Sep 04 19:31:30 2021 +0200
+++ b/CHANGELOG Sat Sep 04 19:40:02 2021 +0200
@@ -1,3 +1,4 @@
+* Add estimation count to ModelStorage
 * Support empty digits in format_number of Report
 * Add digits mixin
 * Use argon2 or scrypt to hash password by default
diff -r 2be0f68b7ac5 -r 6bbc19a57553 doc/ref/models/models.rst
--- a/doc/ref/models/models.rst Sat Sep 04 19:31:30 2021 +0200
+++ b/doc/ref/models/models.rst Sat Sep 04 19:40:02 2021 +0200
@@ -348,6 +348,10 @@
     Yield tuples (record, name, icon) for records matching text.
     It is used for the global search.
 
+.. classmethod:: ModelStorage.count()
+
+    Return an estimation of the number of records stored.
+
 .. classmethod:: ModelStorage.browse(ids)
 
     Return a list of record instance for the ``ids``.
diff -r 2be0f68b7ac5 -r 6bbc19a57553 doc/topics/configuration.rst
--- a/doc/topics/configuration.rst      Sat Sep 04 19:31:30 2021 +0200
+++ b/doc/topics/configuration.rst      Sat Sep 04 19:40:02 2021 +0200
@@ -251,6 +251,21 @@
 
 Default: ``300``
 
+count_timeout
+~~~~~~~~~~~~~
+
+The cache timeout duration in seconds of the estimation of records.
+
+Default: ``86400`` (1 day)
+
+count_clear
+~~~~~~~~~~~
+
+The number of operations after which the counting estimation of records is
+cleared.
+
+Default: ``1000``
+
 queue
 -----
 
diff -r 2be0f68b7ac5 -r 6bbc19a57553 trytond/model/modelstorage.py
--- a/trytond/model/modelstorage.py     Sat Sep 04 19:31:30 2021 +0200
+++ b/trytond/model/modelstorage.py     Sat Sep 04 19:40:02 2021 +0200
@@ -5,6 +5,7 @@
 import datetime
 import time
 import csv
+import random
 
 from decimal import Decimal
 from itertools import islice, chain
@@ -24,13 +25,17 @@
 from trytond.i18n import gettext, lazy_gettext
 from trytond.transaction import Transaction
 from trytond.pool import Pool
-from trytond.cache import LRUDict, LRUDictTransaction, freeze, unfreeze
+from trytond.cache import Cache, LRUDict, LRUDictTransaction, freeze, unfreeze
 from trytond.rpc import RPC
 from .descriptors import dualmethod
 
 __all__ = ['ModelStorage', 'EvalEnvironment']
 _cache_record = config.getint('cache', 'record')
 _cache_field = config.getint('cache', 'field')
+_cache_count_timeout = config.getint(
+    'cache', 'count_timeout', default=60 * 60 * 24)
+_cache_count_clear = config.getint(
+    'cache', 'count_clear', default=1000)
 
 
 class AccessError(UserError):
@@ -110,6 +115,8 @@
     rec_name = fields.Function(
         fields.Char(lazy_gettext('ir.msg_record_name')), 'get_rec_name',
         searcher='search_rec_name')
+    _count_cache = Cache(
+        'modelstorage.count', duration=_cache_count_timeout, context=False)
 
     @classmethod
     def __setup__(cls):
@@ -172,6 +179,13 @@
         # Increase transaction counter
         Transaction().counter += 1
 
+        count = cls._count_cache.get(cls.__name__)
+        if count is not None:
+            if random.random() < 1 / _cache_count_clear:
+                cls._count_cache.set(cls.__name__, None)
+            else:
+                cls._count_cache.set(cls.__name__, count + len(vlist))
+
     @classmethod
     @without_check_access
     def trigger_create(cls, records):
@@ -309,6 +323,13 @@
                 for record in records:
                     cache_cls.pop(record.id, None)
 
+        count = cls._count_cache.get(cls.__name__)
+        if count is not None:
+            if random.random() < 1 / _cache_count_clear:
+                cls._count_cache.set(cls.__name__, None)
+            else:
+                cls._count_cache.set(cls.__name__, count - len(records))
+
     @classmethod
     @without_check_access
     def trigger_delete(cls, records):
@@ -558,6 +579,15 @@
             return domain
         return process(domain)
 
+    @classmethod
+    def count(cls):
+        "Returns the estimation of the number of records."
+        count = cls._count_cache.get(cls.__name__)
+        if count is None:
+            count = cls.search([], count=True)
+            cls._count_cache.set(cls.__name__, count)
+        return count
+
     def resources(self):
         pool = Pool()
         Attachment = pool.get('ir.attachment')

Reply via email to