iter_closest.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. package chord
  2. import (
  3. "math/big"
  4. )
  5. type ClosestPreceedingVnodeIterator struct {
  6. key []byte
  7. vn *LocalVnode
  8. finger_idx int
  9. successor_idx int
  10. yielded map[string]struct{}
  11. }
  12. func (cp *ClosestPreceedingVnodeIterator) Init(vn *LocalVnode, key []byte) {
  13. cp.key = key
  14. cp.vn = vn
  15. cp.successor_idx = len(vn.Successors) - 1
  16. cp.finger_idx = len(vn.Finger) - 1
  17. cp.yielded = make(map[string]struct{})
  18. }
  19. func (cp *ClosestPreceedingVnodeIterator) Next() *Vnode {
  20. // Try to find each node
  21. var successor_node *Vnode
  22. var finger_node *Vnode
  23. // Scan to find the next successor
  24. vn := cp.vn
  25. var i int
  26. for i = cp.successor_idx; i >= 0; i-- {
  27. if vn.Successors[i] == nil {
  28. continue
  29. }
  30. if _, ok := cp.yielded[vn.Successors[i].String()]; ok {
  31. continue
  32. }
  33. if Between(vn.Id, cp.key, vn.Successors[i].Id) {
  34. successor_node = vn.Successors[i]
  35. break
  36. }
  37. }
  38. cp.successor_idx = i
  39. // Scan to find the next Finger
  40. for i = cp.finger_idx; i >= 0; i-- {
  41. if vn.Finger[i] == nil {
  42. continue
  43. }
  44. if _, ok := cp.yielded[vn.Finger[i].String()]; ok {
  45. continue
  46. }
  47. if Between(vn.Id, cp.key, vn.Finger[i].Id) {
  48. finger_node = vn.Finger[i]
  49. break
  50. }
  51. }
  52. cp.finger_idx = i
  53. // Determine which node is better
  54. if successor_node != nil && finger_node != nil {
  55. // Determine the closer node
  56. hb := cp.vn.Ring.Config.HashBits
  57. closest := ClosestPreceedingVnode(successor_node,
  58. finger_node, cp.key, hb)
  59. if closest == successor_node {
  60. cp.successor_idx--
  61. } else {
  62. cp.finger_idx--
  63. }
  64. cp.yielded[closest.String()] = struct{}{}
  65. return closest
  66. } else if successor_node != nil {
  67. cp.successor_idx--
  68. cp.yielded[successor_node.String()] = struct{}{}
  69. return successor_node
  70. } else if finger_node != nil {
  71. cp.finger_idx--
  72. cp.yielded[finger_node.String()] = struct{}{}
  73. return finger_node
  74. }
  75. return nil
  76. }
  77. // Returns the closest preceeding Vnode to the key
  78. func ClosestPreceedingVnode(a, b *Vnode, key []byte, bits int) *Vnode {
  79. a_dist := Distance(a.Id, key, bits)
  80. b_dist := Distance(b.Id, key, bits)
  81. if a_dist.Cmp(b_dist) <= 0 {
  82. return a
  83. } else {
  84. return b
  85. }
  86. }
  87. // Computes the forward Distance from a to b modulus a ring size
  88. func Distance(a, b []byte, bits int) *big.Int {
  89. // Get the ring size
  90. var ring big.Int
  91. ring.Exp(big.NewInt(2), big.NewInt(int64(bits)), nil)
  92. // Convert to int
  93. var a_int, b_int big.Int
  94. (&a_int).SetBytes(a)
  95. (&b_int).SetBytes(b)
  96. // Compute the distances
  97. var dist big.Int
  98. (&dist).Sub(&b_int, &a_int)
  99. // Distance modulus ring size
  100. (&dist).Mod(&dist, &ring)
  101. return &dist
  102. }