Skip to content

Commit 9a40888

Browse files
author
gaffney2010
committed
Changed cache to be keyed on players only.
1 parent 07daefc commit 9a40888

File tree

2 files changed

+24
-16
lines changed

2 files changed

+24
-16
lines changed

axelrod/deterministic_cache.py

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@
1919
from .action import Action
2020
from .player import Player
2121

22-
CachePlayerKey = Tuple[Player, Player, int]
23-
CacheKey = Tuple[str, str, int]
22+
CachePlayerKey = Tuple[Player, Player]
23+
CacheKey = Tuple[str, str]
2424

2525

2626
def _key_transform(key: CachePlayerKey) -> CacheKey:
@@ -29,15 +29,15 @@ def _key_transform(key: CachePlayerKey) -> CacheKey:
2929
Parameters
3030
----------
3131
key: tuple
32-
A 3-tuple: (player instance, player instance, match length)
32+
A 3-tuple: (player instance, player instance)
3333
"""
34-
return key[0].name, key[1].name, key[2]
34+
return key[0].name, key[1].name
3535

3636

3737
def _is_valid_key(key: CachePlayerKey) -> bool:
3838
"""Validate a deterministic cache player key.
3939
40-
The key should always be a 3-tuple, with a pair of axelrod.Player
40+
The key should always be a 2-tuple, with a pair of axelrod.Player
4141
instances and one integer. Both players should be deterministic.
4242
4343
Parameters
@@ -48,13 +48,12 @@ def _is_valid_key(key: CachePlayerKey) -> bool:
4848
-------
4949
Boolean indicating if the key is valid
5050
"""
51-
if not isinstance(key, tuple) or len(key) != 3:
51+
if not isinstance(key, tuple) or len(key) != 2:
5252
return False
5353

5454
if not (
5555
isinstance(key[0], Player)
5656
and isinstance(key[1], Player)
57-
and isinstance(key[2], int)
5857
):
5958
return False
6059

@@ -83,10 +82,11 @@ def _is_valid_value(value: List) -> bool:
8382
class DeterministicCache(UserDict):
8483
"""A class to cache the results of deterministic matches.
8584
86-
For fixed length matches with no noise between pairs of deterministic
87-
players, the results will always be the same. We can hold those results
88-
in this class so as to avoid repeatedly generating them in tournaments
89-
of multiple repetitions.
85+
For matches with no noise between pairs of deterministic players, the
86+
results will always be the same. We can hold the results for the longest
87+
run in this class, so as to avoid repeatedly generating them in tournaments
88+
of multiple repetitions. If a shorter or equal-length match is run, we can
89+
use the stored results.
9090
9191
By also storing those cached results in a file, we can re-use the cache
9292
between multiple tournaments if necessary.
@@ -134,8 +134,7 @@ def __setitem__(self, key: CachePlayerKey, value):
134134

135135
if not _is_valid_key(key):
136136
raise ValueError(
137-
"Key must be a tuple of 2 deterministic axelrod Player classes "
138-
"and an integer"
137+
"Key must be a tuple of 2 deterministic axelrod Player classes"
139138
)
140139

141140
if not _is_valid_value(value):

axelrod/match.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,15 @@ def _cache_update_required(self):
116116
and not (any(p.classifier["stochastic"] for p in self.players))
117117
)
118118

119+
def _cached_enough_turns(self, cache_key, turns):
120+
"""
121+
Returns true iff there are is a entry in self._cache for the given key and
122+
it's at least turns long.
123+
"""
124+
if cache_key not in self._cache:
125+
return False
126+
return len(self._cache[cache_key]) >= turns
127+
119128
def play(self):
120129
"""
121130
The resulting list of actions from a match between two players.
@@ -135,9 +144,9 @@ def play(self):
135144
i.e. One entry per turn containing a pair of actions.
136145
"""
137146
turns = min(sample_length(self.prob_end), self.turns)
138-
cache_key = (self.players[0], self.players[1], turns)
147+
cache_key = (self.players[0], self.players[1])
139148

140-
if self._stochastic or (cache_key not in self._cache):
149+
if self._stochastic or not self._cached_enough_turns(cache_key, turns):
141150
for p in self.players:
142151
p.reset()
143152
p.set_match_attributes(**self.match_attributes)
@@ -148,7 +157,7 @@ def play(self):
148157
if self._cache_update_required:
149158
self._cache[cache_key] = result
150159
else:
151-
result = self._cache[cache_key]
160+
result = self._cache[cache_key][:turns]
152161

153162
self.result = result
154163
return result

0 commit comments

Comments
 (0)