mirror of
https://github.com/Grasscutters/mitmproxy.git
synced 2024-11-23 08:11:00 +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.")
|
signals.status_message.send(message="No content to save.")
|
||||||
|
|
||||||
|
|
||||||
class FlowCache:
|
flowcache = utils.LRUCache(800)
|
||||||
@utils.LRUCache(200)
|
|
||||||
def format_flow(self, *args):
|
|
||||||
return raw_format_flow(*args)
|
|
||||||
flowcache = FlowCache()
|
|
||||||
|
|
||||||
|
|
||||||
def format_flow(f, focus, extended=False, hostheader=False, padding=2):
|
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]
|
d["resp_ctype"] = t[0].split(";")[0]
|
||||||
else:
|
else:
|
||||||
d["resp_ctype"] = ""
|
d["resp_ctype"] = ""
|
||||||
return flowcache.format_flow(
|
return flowcache.get(
|
||||||
|
raw_format_flow,
|
||||||
tuple(sorted(d.items())), focus, extended, padding
|
tuple(sorted(d.items())), focus, extended, padding
|
||||||
)
|
)
|
||||||
|
@ -107,16 +107,7 @@ class FlowViewHeader(urwid.WidgetWrap):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class CallbackCache:
|
cache = utils.LRUCache(200)
|
||||||
@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()
|
|
||||||
|
|
||||||
|
|
||||||
class FlowView(urwid.WidgetWrap):
|
class FlowView(urwid.WidgetWrap):
|
||||||
@ -158,8 +149,8 @@ class FlowView(urwid.WidgetWrap):
|
|||||||
limit = sys.maxint
|
limit = sys.maxint
|
||||||
else:
|
else:
|
||||||
limit = contentview.VIEW_CUTOFF
|
limit = contentview.VIEW_CUTOFF
|
||||||
description, text_objects = cache.callback(
|
description, text_objects = cache.get(
|
||||||
self, "_cached_content_view",
|
self._cached_content_view,
|
||||||
viewmode,
|
viewmode,
|
||||||
tuple(tuple(i) for i in conn.headers.lst),
|
tuple(tuple(i) for i in conn.headers.lst),
|
||||||
conn.content,
|
conn.content,
|
||||||
|
@ -119,40 +119,33 @@ pkg_data = Data(__name__)
|
|||||||
|
|
||||||
class LRUCache:
|
class LRUCache:
|
||||||
"""
|
"""
|
||||||
A decorator that implements a self-expiring LRU cache for class
|
A simple LRU cache for generated values.
|
||||||
methods (not functions!).
|
|
||||||
|
|
||||||
Cache data is tracked as attributes on the object itself. There is
|
|
||||||
therefore a separate cache for each object instance.
|
|
||||||
"""
|
"""
|
||||||
def __init__(self, size=100):
|
def __init__(self, size=100):
|
||||||
self.size = size
|
self.size = size
|
||||||
|
self.cache = {}
|
||||||
|
self.cacheList = []
|
||||||
|
|
||||||
def __call__(self, f):
|
def get(self, gen, *args):
|
||||||
cacheName = "_cached_%s"%f.__name__
|
"""
|
||||||
cacheListName = "_cachelist_%s"%f.__name__
|
gen: A (presumably expensive) generator function. The identity of
|
||||||
size = self.size
|
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 = 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
|
||||||
|
|
||||||
@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]
|
|
||||||
else:
|
|
||||||
ret = f(self, *args)
|
|
||||||
cacheList.insert(0, args)
|
|
||||||
cache[args] = ret
|
|
||||||
if len(cacheList) > size:
|
|
||||||
d = cacheList.pop()
|
|
||||||
cache.pop(d)
|
|
||||||
return ret
|
|
||||||
return wrap
|
|
||||||
|
|
||||||
def parse_content_type(c):
|
def parse_content_type(c):
|
||||||
"""
|
"""
|
||||||
|
@ -67,33 +67,34 @@ def test_pretty_duration():
|
|||||||
assert utils.pretty_duration(0.123) == "123ms"
|
assert utils.pretty_duration(0.123) == "123ms"
|
||||||
|
|
||||||
def test_LRUCache():
|
def test_LRUCache():
|
||||||
|
cache = utils.LRUCache(2)
|
||||||
class Foo:
|
class Foo:
|
||||||
ran = False
|
ran = False
|
||||||
@utils.LRUCache(2)
|
def gen(self, x):
|
||||||
def one(self, x):
|
|
||||||
self.ran = True
|
self.ran = True
|
||||||
return x
|
return x
|
||||||
|
|
||||||
f = Foo()
|
f = Foo()
|
||||||
assert f.one(1) == 1
|
|
||||||
|
assert not f.ran
|
||||||
|
assert cache.get(f.gen, 1) == 1
|
||||||
assert f.ran
|
assert f.ran
|
||||||
f.ran = False
|
f.ran = False
|
||||||
assert f.one(1) == 1
|
assert cache.get(f.gen, 1) == 1
|
||||||
assert not f.ran
|
assert not f.ran
|
||||||
|
|
||||||
f.ran = False
|
f.ran = False
|
||||||
assert f.one(1) == 1
|
assert cache.get(f.gen, 1) == 1
|
||||||
assert not f.ran
|
assert not f.ran
|
||||||
assert f.one(2) == 2
|
assert cache.get(f.gen, 2) == 2
|
||||||
assert f.one(3) == 3
|
assert cache.get(f.gen, 3) == 3
|
||||||
assert f.ran
|
assert f.ran
|
||||||
|
|
||||||
f.ran = False
|
f.ran = False
|
||||||
assert f.one(1) == 1
|
assert cache.get(f.gen, 1) == 1
|
||||||
assert f.ran
|
assert f.ran
|
||||||
|
|
||||||
assert len(f._cached_one) == 2
|
assert len(cache.cacheList) == 2
|
||||||
assert len(f._cachelist_one) == 2
|
assert len(cache.cache) == 2
|
||||||
|
|
||||||
|
|
||||||
def test_unparse_url():
|
def test_unparse_url():
|
||||||
@ -128,4 +129,3 @@ def test_safe_subn():
|
|||||||
|
|
||||||
def test_urlencode():
|
def test_urlencode():
|
||||||
assert utils.urlencode([('foo','bar')])
|
assert utils.urlencode([('foo','bar')])
|
||||||
|
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
# Generate a test pattern with pathoc
|
# Generate a test pattern with pathoc
|
||||||
PATHOD=http://localhost:9999
|
PATHOD=http://localhost:9999
|
||||||
pathoc localhost:8080 "get:'$PATHOD/p/200: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@200b':b@200b"
|
pathoc localhost:8080 "get:'$PATHOD/p/300:p0,1:b@2048b':b@2048b"
|
||||||
pathoc localhost:8080 "get:'$PATHOD/p/400:p0,1:b@200b':b@200b"
|
pathoc localhost:8080 "get:'$PATHOD/p/400:p0,1:b@2048b':b@2048b"
|
||||||
pathoc localhost:8080 "get:'$PATHOD/p/500:p0,1:b@200b':b@200b"
|
pathoc localhost:8080 "get:'$PATHOD/p/500:p0,1:b@2048b':b@2048b"
|
||||||
pathoc localhost:8080 "get:'$PATHOD/p/600:p0,1:b@200b':b@200b"
|
pathoc localhost:8080 "get:'$PATHOD/p/600:p0,1:b@2048b':b@2048b"
|
||||||
|
Loading…
Reference in New Issue
Block a user