Add __len__ and __bool__ to cache iterators - #74
Conversation
|
Thank you. There's a lot of changes, I’ll review and merge them very soon. I have doubts about some things and need to check them. In cases where the |
Co-authored-by: chiri <chirizxc@proton.me>
Co-authored-by: chiri <chirizxc@proton.me>
|
Thanks for the quick reply and for the trust! Please take your time, there is no rush at all. The doubt is fair, and that exact case was not covered, so I have just added a test for it: |
Closes #73
The iterator types behind
keys(),values()anditems()get__len__and__bool__.len()says how many items the iterator will yield: for a freshcache.keys()that is the number of live entries, the same number adictview would report, and it goes down as a stored iterator is consumed, like any Python iterator.operator.length_hint()picks it up automatically, andbool()of an empty iterator becomes False instead of True, which is the point of the change.On
Cache,FIFOCache,LRUCache,LFUCacheandRRCachethe count is O(1). OnTTLCacheandVTTLCacheit walks the entries and skips the expired ones, so it is O(n): the number has to match what the walk actually yields. Therelen(cache.keys())can be smaller thanlen(cache), because an expired entry can sit behind a live one, and only the walk skips it. cachetools counts cheaper because its update moves the entry to the back, so everything expired sits at the head. In cachebox an update refreshesexpires_atin place, so an exact count is either a walk on everylen(), or a separate counter paid for on every insert. I picked the walk:len()is called rarely, inserts happen all the time.If the cache changed after the iterator was created,
len()andbool()raise the same RuntimeError that__next__already raises: the iterator's existing rule extended to the new methods, not a new restriction.Six new tests: four in the shared mixin, so they run for all seven types, and two for the expired-entry cases on
TTLCacheandVTTLCache.