k-nearest-nodes.go.go 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. package k_nearest_nodes
  2. import (
  3. "hash/maphash"
  4. "github.com/anacrolix/multiless"
  5. "github.com/benbjohnson/immutable"
  6. "github.com/anacrolix/dht/v2/int160"
  7. "github.com/anacrolix/dht/v2/krpc"
  8. )
  9. type Key = krpc.NodeInfo
  10. type Elem struct {
  11. Key
  12. Data interface{}
  13. }
  14. type Type struct {
  15. inner *immutable.SortedMap
  16. k int
  17. }
  18. func New(target int160.T, k int) Type {
  19. seed := maphash.MakeSeed()
  20. return Type{
  21. k: k,
  22. inner: immutable.NewSortedMap(lessComparer{less: func(_l, _r interface{}) bool {
  23. l := _l.(Key)
  24. r := _r.(Key)
  25. return multiless.New().Cmp(
  26. l.ID.Int160().Distance(target).Cmp(r.ID.Int160().Distance(target)),
  27. ).Lazy(func() multiless.Computation {
  28. var lh, rh maphash.Hash
  29. lh.SetSeed(seed)
  30. rh.SetSeed(seed)
  31. lh.WriteString(l.Addr.String())
  32. rh.WriteString(r.Addr.String())
  33. return multiless.New().Int64(int64(lh.Sum64()), int64(rh.Sum64()))
  34. }).Less()
  35. }}),
  36. }
  37. }
  38. func (me *Type) Range(f func(Elem)) {
  39. iter := me.inner.Iterator()
  40. for !iter.Done() {
  41. key, value := iter.Next()
  42. f(Elem{
  43. Key: key.(Key),
  44. Data: value,
  45. })
  46. }
  47. }
  48. func (me Type) Len() int {
  49. return me.inner.Len()
  50. }
  51. func (me Type) Push(elem Elem) Type {
  52. me.inner = me.inner.Set(elem.Key, elem.Data)
  53. for me.inner.Len() > me.k {
  54. iter := me.inner.Iterator()
  55. iter.Last()
  56. key, _ := iter.Next()
  57. me.inner = me.inner.Delete(key)
  58. }
  59. return me
  60. }
  61. func (me Type) Farthest() (elem Elem) {
  62. iter := me.inner.Iterator()
  63. iter.Last()
  64. if iter.Done() {
  65. panic(me.k)
  66. }
  67. key, value := iter.Next()
  68. return Elem{
  69. Key: key.(Key),
  70. Data: value,
  71. }
  72. }
  73. func (me Type) Full() bool {
  74. return me.Len() >= me.k
  75. }
  76. type lessFunc func(l, r interface{}) bool
  77. type lessComparer struct {
  78. less lessFunc
  79. }
  80. func (me lessComparer) Compare(i, j interface{}) int {
  81. if me.less(i, j) {
  82. return -1
  83. } else if me.less(j, i) {
  84. return 1
  85. } else {
  86. return 0
  87. }
  88. }