mirror of
https://github.com/Grasscutters/mitmproxy.git
synced 2024-11-27 02:24:18 +00:00
Replace far-too-clever decorator LRU cache with something simpler
This commit is contained in:
parent
a2da38cc83
commit
842e23d3e3
@ -327,11 +327,7 @@ def ask_save_body(part, master, state, flow):
|
||||
signals.status_message.send(message="No content to save.")
|
||||
|
||||
|
||||
class FlowCache:
|
||||
@utils.LRUCache(200)
|
||||
def format_flow(self, *args):
|
||||
return raw_format_flow(*args)
|
||||
flowcache = FlowCache()
|
||||
flowcache = utils.LRUCache(800)
|
||||
|
||||
|
||||
def format_flow(f, focus, extended=False, hostheader=False, padding=2):
|
||||
@ -370,6 +366,7 @@ def format_flow(f, focus, extended=False, hostheader=False, padding=2):
|
||||
d["resp_ctype"] = t[0].split(";")[0]
|
||||
else:
|
||||
d["resp_ctype"] = ""
|
||||
return flowcache.format_flow(
|
||||
return flowcache.get(
|
||||
raw_format_flow,
|
||||
tuple(sorted(d.items())), focus, extended, padding
|
||||
)
|
||||
|
@ -107,16 +107,7 @@ class FlowViewHeader(urwid.WidgetWrap):
|
||||
)
|
||||
|
||||
|
||||
class CallbackCache:
|
||||
@utils.LRUCache(200)
|
||||
def _callback(self, method, *args, **kwargs):
|
||||
return getattr(self.obj, method)(*args, **kwargs)
|
||||
|
||||
def callback(self, obj, method, *args, **kwargs):
|
||||
# obj varies!
|
||||
self.obj = obj
|
||||
return self._callback(method, *args, **kwargs)
|
||||
cache = CallbackCache()
|
||||
cache = utils.LRUCache(200)
|
||||
|
||||
|
||||
class FlowView(urwid.WidgetWrap):
|
||||
@ -158,8 +149,8 @@ class FlowView(urwid.WidgetWrap):
|
||||
limit = sys.maxint
|
||||
else:
|
||||
limit = contentview.VIEW_CUTOFF
|
||||
description, text_objects = cache.callback(
|
||||
self, "_cached_content_view",
|
||||
description, text_objects = cache.get(
|
||||
self._cached_content_view,
|
||||
viewmode,
|
||||
tuple(tuple(i) for i in conn.headers.lst),
|
||||
conn.content,
|
||||
|
@ -119,40 +119,33 @@ pkg_data = Data(__name__)
|
||||
|
||||
class LRUCache:
|
||||
"""
|
||||
A decorator that implements a self-expiring LRU cache for class
|
||||
methods (not functions!).
|
||||
|
||||
Cache data is tracked as attributes on the object itself. There is
|
||||
therefore a separate cache for each object instance.
|
||||
A simple LRU cache for generated values.
|
||||
"""
|
||||
def __init__(self, size=100):
|
||||
self.size = size
|
||||
self.cache = {}
|
||||
self.cacheList = []
|
||||
|
||||
def __call__(self, f):
|
||||
cacheName = "_cached_%s"%f.__name__
|
||||
cacheListName = "_cachelist_%s"%f.__name__
|
||||
size = self.size
|
||||
|
||||
@functools.wraps(f)
|
||||
def wrap(self, *args):
|
||||
if not hasattr(self, cacheName):
|
||||
setattr(self, cacheName, {})
|
||||
setattr(self, cacheListName, [])
|
||||
cache = getattr(self, cacheName)
|
||||
cacheList = getattr(self, cacheListName)
|
||||
if cache.has_key(args):
|
||||
cacheList.remove(args)
|
||||
cacheList.insert(0, args)
|
||||
return cache[args]
|
||||
def get(self, gen, *args):
|
||||
"""
|
||||
gen: A (presumably expensive) generator function. The identity of
|
||||
gen is NOT taken into account by the cache.
|
||||
*args: A list of immutable arguments, used to establish identiy by
|
||||
*the cache, and passed to gen to generate values.
|
||||
"""
|
||||
if self.cache.has_key(args):
|
||||
self.cacheList.remove(args)
|
||||
self.cacheList.insert(0, args)
|
||||
return self.cache[args]
|
||||
else:
|
||||
ret = f(self, *args)
|
||||
cacheList.insert(0, args)
|
||||
cache[args] = ret
|
||||
if len(cacheList) > size:
|
||||
d = cacheList.pop()
|
||||
cache.pop(d)
|
||||
ret = gen(*args)
|
||||
self.cacheList.insert(0, args)
|
||||
self.cache[args] = ret
|
||||
if len(self.cacheList) > self.size:
|
||||
d = self.cacheList.pop()
|
||||
self.cache.pop(d)
|
||||
return ret
|
||||
return wrap
|
||||
|
||||
|
||||
def parse_content_type(c):
|
||||
"""
|
||||
|
@ -67,33 +67,34 @@ def test_pretty_duration():
|
||||
assert utils.pretty_duration(0.123) == "123ms"
|
||||
|
||||
def test_LRUCache():
|
||||
cache = utils.LRUCache(2)
|
||||
class Foo:
|
||||
ran = False
|
||||
@utils.LRUCache(2)
|
||||
def one(self, x):
|
||||
def gen(self, x):
|
||||
self.ran = True
|
||||
return x
|
||||
|
||||
f = Foo()
|
||||
assert f.one(1) == 1
|
||||
|
||||
assert not f.ran
|
||||
assert cache.get(f.gen, 1) == 1
|
||||
assert f.ran
|
||||
f.ran = False
|
||||
assert f.one(1) == 1
|
||||
assert cache.get(f.gen, 1) == 1
|
||||
assert not f.ran
|
||||
|
||||
f.ran = False
|
||||
assert f.one(1) == 1
|
||||
assert cache.get(f.gen, 1) == 1
|
||||
assert not f.ran
|
||||
assert f.one(2) == 2
|
||||
assert f.one(3) == 3
|
||||
assert cache.get(f.gen, 2) == 2
|
||||
assert cache.get(f.gen, 3) == 3
|
||||
assert f.ran
|
||||
|
||||
f.ran = False
|
||||
assert f.one(1) == 1
|
||||
assert cache.get(f.gen, 1) == 1
|
||||
assert f.ran
|
||||
|
||||
assert len(f._cached_one) == 2
|
||||
assert len(f._cachelist_one) == 2
|
||||
assert len(cache.cacheList) == 2
|
||||
assert len(cache.cache) == 2
|
||||
|
||||
|
||||
def test_unparse_url():
|
||||
@ -128,4 +129,3 @@ def test_safe_subn():
|
||||
|
||||
def test_urlencode():
|
||||
assert utils.urlencode([('foo','bar')])
|
||||
|
||||
|
@ -2,8 +2,8 @@
|
||||
|
||||
# Generate a test pattern with pathoc
|
||||
PATHOD=http://localhost:9999
|
||||
pathoc localhost:8080 "get:'$PATHOD/p/200:p0,1:b@200b':b@200b"
|
||||
pathoc localhost:8080 "get:'$PATHOD/p/300:p0,1:b@200b':b@200b"
|
||||
pathoc localhost:8080 "get:'$PATHOD/p/400:p0,1:b@200b':b@200b"
|
||||
pathoc localhost:8080 "get:'$PATHOD/p/500:p0,1:b@200b':b@200b"
|
||||
pathoc localhost:8080 "get:'$PATHOD/p/600:p0,1:b@200b':b@200b"
|
||||
pathoc localhost:8080 "get:'$PATHOD/p/200:p0,1:b@2048b':b@2048b"
|
||||
pathoc localhost:8080 "get:'$PATHOD/p/300:p0,1:b@2048b':b@2048b"
|
||||
pathoc localhost:8080 "get:'$PATHOD/p/400:p0,1:b@2048b':b@2048b"
|
||||
pathoc localhost:8080 "get:'$PATHOD/p/500:p0,1:b@2048b':b@2048b"
|
||||
pathoc localhost:8080 "get:'$PATHOD/p/600:p0,1:b@2048b':b@2048b"
|
||||
|
Loading…
Reference in New Issue
Block a user