2525 consuming from the token iterator one token at a time.
2626
2727"""
28- import random
29-
3028from jmespath import lexer
3129from jmespath .compat import with_repr_method
3230from jmespath import ast
@@ -73,7 +71,7 @@ class Parser(object):
7371 # The _MAX_SIZE most recent expressions are cached in
7472 # _CACHE dict.
7573 _CACHE = {}
76- _MAX_SIZE = 128
74+ _MAX_SIZE = 512
7775
7876 def __init__ (self , lookahead = 2 ):
7977 self .tokenizer = None
@@ -82,13 +80,26 @@ def __init__(self, lookahead=2):
8280 self ._index = 0
8381
8482 def parse (self , expression ):
85- cached = self ._CACHE .get (expression )
86- if cached is not None :
87- return cached
83+ try :
84+ return self ._CACHE [expression ]
85+ except KeyError :
86+ pass
8887 parsed_result = self ._do_parse (expression )
88+ if len (self ._CACHE ) >= self ._MAX_SIZE :
89+ try :
90+ del self ._CACHE [next (iter (self ._CACHE ))]
91+ except (KeyError , StopIteration , RuntimeError ):
92+ # KeyError - Another thread else already deleted the key.
93+ # RuntimeError - Another modified the cache.
94+ # StopIteration - (Unlikely) Cache is empty.
95+ #
96+ # If we encounter an error we should NOT be adding to the
97+ # cache. To ensure we do not exceed self._MAX_SIZE, we
98+ # can only add to the cache if we successfully removed
99+ # an element from the cache, otherwise this can grow
100+ # unbounded.
101+ return parsed_result
89102 self ._CACHE [expression ] = parsed_result
90- if len (self ._CACHE ) > self ._MAX_SIZE :
91- self ._free_cache_entries ()
92103 return parsed_result
93104
94105 def _do_parse (self , expression ):
@@ -488,10 +499,6 @@ def _raise_parse_error_maybe_eof(self, expected_type, token):
488499 raise exceptions .ParseError (
489500 lex_position , actual_value , actual_type , message )
490501
491- def _free_cache_entries (self ):
492- for key in random .sample (list (self ._CACHE .keys ()), int (self ._MAX_SIZE / 2 )):
493- self ._CACHE .pop (key , None )
494-
495502 @classmethod
496503 def purge (cls ):
497504 """Clear the expression compilation cache."""
0 commit comments