ordered-bitmap.go 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. package torrent
  2. import (
  3. g "github.com/anacrolix/generics"
  4. list "github.com/bahlo/generic-list-go"
  5. "iter"
  6. "github.com/anacrolix/torrent/typed-roaring"
  7. )
  8. type orderedBitmap[T typedRoaring.BitConstraint] struct {
  9. bitmap typedRoaring.Bitmap[T]
  10. // There should be way more efficient ways to do this.
  11. order list.List[T]
  12. elements map[T]*list.Element[T]
  13. }
  14. func (o *orderedBitmap[T]) IterateSnapshot(f func(T) bool) {
  15. o.bitmap.Clone().Iterate(f)
  16. }
  17. func (o *orderedBitmap[T]) IsEmpty() bool {
  18. return o.bitmap.IsEmpty()
  19. }
  20. func (o *orderedBitmap[T]) GetCardinality() uint64 {
  21. return uint64(o.order.Len())
  22. }
  23. func (o *orderedBitmap[T]) Contains(index T) bool {
  24. return o.bitmap.Contains(index)
  25. }
  26. func (o *orderedBitmap[T]) Add(index T) {
  27. o.bitmap.Add(index)
  28. if _, ok := o.elements[index]; !ok {
  29. g.MakeMapIfNilAndSet(&o.elements, index, o.order.PushBack(index))
  30. }
  31. }
  32. func (o *orderedBitmap[T]) Rank(index T) uint64 {
  33. return o.bitmap.Rank(index)
  34. }
  35. func (o *orderedBitmap[T]) Iterate(f func(T) bool) (all bool) {
  36. for e := o.order.Front(); e != nil; e = e.Next() {
  37. if !f(e.Value) {
  38. return
  39. }
  40. }
  41. all = true
  42. return
  43. }
  44. func (o *orderedBitmap[T]) Iterator() iter.Seq[T] {
  45. return func(yield func(T) bool) {
  46. for e := o.order.Front(); e != nil; e = e.Next() {
  47. if !yield(e.Value) {
  48. return
  49. }
  50. }
  51. }
  52. }
  53. func (o *orderedBitmap[T]) CheckedRemove(index T) bool {
  54. if !o.bitmap.CheckedRemove(index) {
  55. return false
  56. }
  57. o.order.Remove(o.elements[index])
  58. delete(o.elements, index)
  59. return true
  60. }