Add memoization for has_changes
This commit is contained in:
committed by
Andy Armstrong
parent
3afc125ecb
commit
1db107c2ce
@@ -28,6 +28,7 @@ from opaque_keys.edx.keys import UsageKey
|
||||
|
||||
from .access import has_course_access
|
||||
from django.utils.translation import ugettext as _
|
||||
from models.settings.course_grading import CourseGradingModel
|
||||
|
||||
__all__ = ['OPEN_ENDED_COMPONENT_TYPES',
|
||||
'ADVANCED_COMPONENT_POLICY_KEY',
|
||||
|
||||
@@ -571,7 +571,7 @@ def _get_xblock(usage_key, user):
|
||||
"""
|
||||
store = modulestore()
|
||||
try:
|
||||
return store.get_item(usage_key)
|
||||
return store.get_item(usage_key, depth=None)
|
||||
except ItemNotFoundError:
|
||||
if usage_key.category in CREATE_IF_NOT_FOUND:
|
||||
# Create a new one for certain categories only. Used for course info handouts.
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
"""Tests for items views."""
|
||||
import os
|
||||
import json
|
||||
from datetime import datetime, timedelta
|
||||
import ddt
|
||||
from unittest import skipUnless
|
||||
|
||||
from mock import patch
|
||||
from pytz import UTC
|
||||
|
||||
@@ -24,6 +24,7 @@ from opaque_keys import InvalidKeyError
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
from xblock.runtime import Mixologist
|
||||
from xblock.core import XBlock
|
||||
import functools
|
||||
|
||||
log = logging.getLogger('edx.modulestore')
|
||||
|
||||
@@ -559,6 +560,36 @@ class ModuleStoreReadBase(ModuleStoreRead):
|
||||
raise ValueError(u"Cannot set default store to type {}".format(store_type))
|
||||
yield
|
||||
|
||||
@staticmethod
|
||||
def memoize_request_cache(func):
|
||||
"""
|
||||
Memoize a function call results on the request_cache if there's one. Creates the cache key by
|
||||
joining the unicode of all the args with &; so, if your arg may use the default &, it may
|
||||
have false hits
|
||||
"""
|
||||
@functools.wraps(func)
|
||||
def wrapper(self, *args, **kwargs):
|
||||
if self.request_cache:
|
||||
cache_key = '&'.join([hashvalue(arg) for arg in args])
|
||||
if cache_key in self.request_cache.data.setdefault(func.__name__, {}):
|
||||
return self.request_cache.data[func.__name__][cache_key]
|
||||
|
||||
result = func(self, *args, **kwargs)
|
||||
|
||||
self.request_cache.data[func.__name__][cache_key] = result
|
||||
return result
|
||||
else:
|
||||
return func(self, *args, **kwargs)
|
||||
return wrapper
|
||||
|
||||
def hashvalue(arg):
|
||||
"""
|
||||
If arg is an xblock, use its location. otherwise just turn it into a string
|
||||
"""
|
||||
if isinstance(arg, XBlock):
|
||||
return unicode(arg.location)
|
||||
else:
|
||||
return unicode(arg)
|
||||
|
||||
class ModuleStoreWriteBase(ModuleStoreReadBase, ModuleStoreWrite):
|
||||
'''
|
||||
|
||||
@@ -589,13 +589,13 @@ class DraftModuleStore(MongoModuleStore):
|
||||
_internal([root_usage.to_deprecated_son() for root_usage in root_usages])
|
||||
self.collection.remove({'_id': {'$in': to_be_deleted}}, safe=self.collection.safe)
|
||||
|
||||
@MongoModuleStore.memoize_request_cache
|
||||
def has_changes(self, xblock):
|
||||
"""
|
||||
Check if the xblock or its children have been changed since the last publish.
|
||||
:param xblock: xblock to check
|
||||
:return: True if the draft and published versions differ
|
||||
"""
|
||||
|
||||
# don't check children if this block has changes (is not public)
|
||||
if self.compute_publish_state(xblock) != PublishState.public:
|
||||
return True
|
||||
|
||||
Reference in New Issue
Block a user