You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

82 lines
1.5 KiB

  1. package db
  2. import "bytes"
  3. // A wrapper around itr that tries to keep the iterator
  4. // within the bounds as defined by `prefix`
  5. type prefixIterator struct {
  6. itr Iterator
  7. prefix []byte
  8. invalid bool
  9. }
  10. func (pi *prefixIterator) Seek(key []byte) {
  11. if !bytes.HasPrefix(key, pi.prefix) {
  12. pi.invalid = true
  13. return
  14. }
  15. pi.itr.Seek(key)
  16. pi.checkInvalid()
  17. }
  18. func (pi *prefixIterator) checkInvalid() {
  19. if !pi.itr.Valid() {
  20. pi.invalid = true
  21. }
  22. }
  23. func (pi *prefixIterator) Valid() bool {
  24. if pi.invalid {
  25. return false
  26. }
  27. key := pi.itr.Key()
  28. ok := bytes.HasPrefix(key, pi.prefix)
  29. if !ok {
  30. pi.invalid = true
  31. return false
  32. }
  33. return true
  34. }
  35. func (pi *prefixIterator) Next() {
  36. if pi.invalid {
  37. panic("prefixIterator Next() called when invalid")
  38. }
  39. pi.itr.Next()
  40. pi.checkInvalid()
  41. }
  42. func (pi *prefixIterator) Prev() {
  43. if pi.invalid {
  44. panic("prefixIterator Prev() called when invalid")
  45. }
  46. pi.itr.Prev()
  47. pi.checkInvalid()
  48. }
  49. func (pi *prefixIterator) Key() []byte {
  50. if pi.invalid {
  51. panic("prefixIterator Key() called when invalid")
  52. }
  53. return pi.itr.Key()
  54. }
  55. func (pi *prefixIterator) Value() []byte {
  56. if pi.invalid {
  57. panic("prefixIterator Value() called when invalid")
  58. }
  59. return pi.itr.Value()
  60. }
  61. func (pi *prefixIterator) Close() { pi.itr.Close() }
  62. func (pi *prefixIterator) GetError() error { return pi.itr.GetError() }
  63. func IteratePrefix(db DB, prefix []byte) Iterator {
  64. itr := db.Iterator()
  65. pi := &prefixIterator{
  66. itr: itr,
  67. prefix: prefix,
  68. }
  69. pi.Seek(prefix)
  70. return pi
  71. }