| 41 | 1 #!/usr/bin/env python2 | 
|  | 2 # | 
|  | 3 # Copyright 2011-2016 Google Inc. | 
|  | 4 # | 
|  | 5 # Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | 6 # you may not use this file except in compliance with the License. | 
|  | 7 # You may obtain a copy of the License at | 
|  | 8 # | 
|  | 9 #      http://www.apache.org/licenses/LICENSE-2.0 | 
|  | 10 # | 
|  | 11 # Unless required by applicable law or agreed to in writing, software | 
|  | 12 # distributed under the License is distributed on an "AS IS" BASIS, | 
|  | 13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | 14 # See the License for the specific language governing permissions and | 
|  | 15 # limitations under the License. | 
|  | 16 # | 
|  | 17 # vim: sw=2 sts=2 et | 
|  | 18 | 
|  | 19 class CachingFuncSequence(object): | 
|  | 20     def __init__(self, func, length, inc_func=None): | 
|  | 21         """ | 
|  | 22         length: Length of this sequence. | 
|  | 23         func: function(index) | 
|  | 24         inc_func: function(index, value_of_previous) | 
|  | 25         """ | 
|  | 26 | 
|  | 27         self.func = func | 
|  | 28         self.inc_func = inc_func | 
|  | 29         self.length = length | 
|  | 30         self._cache = {} | 
|  | 31 | 
|  | 32     def __getitem__(self, i): | 
|  | 33         if i < 0: | 
|  | 34             i += self.length | 
|  | 35         if i < 0 or i >= self.length: | 
|  | 36             raise IndexError() | 
|  | 37 | 
|  | 38         v = self._cache.get(i) | 
|  | 39         if v is not None: | 
|  | 40             return v | 
|  | 41 | 
|  | 42         if self.inc_func and i-1 in self._cache: | 
|  | 43             v = self.inc_func(i, self._cache[i-1]) | 
|  | 44         else: | 
|  | 45             v = self.func(i) | 
|  | 46 | 
|  | 47         self._cache[i] = v | 
|  | 48         return v | 
|  | 49 | 
|  | 50     def __len__(self): | 
|  | 51         return self.length | 
|  | 52 | 
|  | 53     def __iter__(self): | 
|  | 54         for i in range(self.length): | 
|  | 55             yield self[i] |