util.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. package chord
  2. import (
  3. "bytes"
  4. "fmt"
  5. "math/big"
  6. "math/rand"
  7. "time"
  8. )
  9. // Generates a random stabilization time
  10. func RandStabilize(conf *Config) time.Duration {
  11. min := conf.StabilizeMin
  12. max := conf.StabilizeMax
  13. r := rand.Float64()
  14. return time.Duration((r * float64(max-min)) + float64(min))
  15. }
  16. // Checks if a key is STRICTLY between two ID's exclusively
  17. func Between(id1, id2, key []byte) bool {
  18. // Check for ring wrap around
  19. if bytes.Compare(id1, id2) == 1 {
  20. return bytes.Compare(id1, key) == -1 ||
  21. bytes.Compare(id2, key) == 1
  22. }
  23. // Handle the normal case
  24. return bytes.Compare(id1, key) == -1 &&
  25. bytes.Compare(id2, key) == 1
  26. }
  27. // Checks if a key is between two ID's, right inclusive
  28. func BetweenRightIncl(id1, id2, key []byte) bool {
  29. // Check for ring wrap around
  30. if bytes.Compare(id1, id2) == 1 {
  31. return bytes.Compare(id1, key) == -1 ||
  32. bytes.Compare(id2, key) >= 0
  33. }
  34. return bytes.Compare(id1, key) == -1 &&
  35. bytes.Compare(id2, key) >= 0
  36. }
  37. // Computes the offset by (n + 2^exp) % (2^mod)
  38. func PowerOffset(id []byte, exp int, mod int) []byte {
  39. // Copy the existing slice
  40. off := make([]byte, len(id))
  41. copy(off, id)
  42. // Convert the ID to a bigint
  43. idInt := big.Int{}
  44. idInt.SetBytes(id)
  45. // Get the offset
  46. two := big.NewInt(2)
  47. offset := big.Int{}
  48. offset.Exp(two, big.NewInt(int64(exp)), nil)
  49. // Sum
  50. sum := big.Int{}
  51. sum.Add(&idInt, &offset)
  52. // Get the ceiling
  53. ceil := big.Int{}
  54. ceil.Exp(two, big.NewInt(int64(mod)), nil)
  55. // Apply the mod
  56. idInt.Mod(&sum, &ceil)
  57. // Add together
  58. return idInt.Bytes()
  59. }
  60. // max returns the max of two ints
  61. func Max(a, b int) int {
  62. if a >= b {
  63. return a
  64. } else {
  65. return b
  66. }
  67. }
  68. // min returns the min of two ints
  69. func Min(a, b int) int {
  70. if a <= b {
  71. return a
  72. } else {
  73. return b
  74. }
  75. }
  76. // Returns the vnode nearest a key
  77. func NearestVnodeToKey(Vnodes []*Vnode, key []byte) *Vnode {
  78. for i := len(Vnodes) - 1; i >= 0; i-- {
  79. if bytes.Compare(Vnodes[i].Id, key) == -1 {
  80. return Vnodes[i]
  81. }
  82. }
  83. // Return the last vnode
  84. return Vnodes[len(Vnodes)-1]
  85. }
  86. // Merges errors together
  87. func MergeErrors(err1, err2 error) error {
  88. if err1 == nil {
  89. return err2
  90. } else if err2 == nil {
  91. return err1
  92. } else {
  93. return fmt.Errorf("%s\n%s", err1, err2)
  94. }
  95. }