Level / abstract-level

Abstract class for a lexicographically sorted key-value database.
MIT License
128 stars 8 forks source link

Keep track of iterator end in `_nextv()` fallback #19

Closed vweevers closed 1 year ago

vweevers commented 2 years ago

Currently, nextv() can only signal the natural end of an iterator by yielding an empty array. In the fallback _nextv() implementation below, when _next() signals end by yielding an undefined key and/or value (line 147), this means _nextv() does not signal end (line 148, unless acc is empty). Consequently, a consumer will call nextv() again, which means we call _next() again (line 160) which has already signaled end.

Whether that's a problem depends on implementation. It is in many-level (the replacement for multileveldown that I'm working on atm, and can easily have its own fix) and could be in others too. It's not a problem for implementations written so far (memory-level, classic-level, browser-level) because those implement their own optimized _nextv().

Solution: set a new private kEnded property to true on line 148, and check that it's false before calling _next(). A seek() should reset it to false. Maybe use kEnded in more places, as a general protection.

https://github.com/Level/abstract-level/blob/601b47c36903760c3232907423645833206871f5/abstract-iterator.js#L142-L161