123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112 |
- package chord
- import (
- "bytes"
- "fmt"
- "math/big"
- "math/rand"
- "time"
- )
- // Generates a random stabilization time
- func RandStabilize(conf *Config) time.Duration {
- min := conf.StabilizeMin
- max := conf.StabilizeMax
- r := rand.Float64()
- return time.Duration((r * float64(max-min)) + float64(min))
- }
- // Checks if a key is STRICTLY between two ID's exclusively
- func Between(id1, id2, key []byte) bool {
- // Check for ring wrap around
- if bytes.Compare(id1, id2) == 1 {
- return bytes.Compare(id1, key) == -1 ||
- bytes.Compare(id2, key) == 1
- }
- // Handle the normal case
- return bytes.Compare(id1, key) == -1 &&
- bytes.Compare(id2, key) == 1
- }
- // Checks if a key is between two ID's, right inclusive
- func BetweenRightIncl(id1, id2, key []byte) bool {
- // Check for ring wrap around
- if bytes.Compare(id1, id2) == 1 {
- return bytes.Compare(id1, key) == -1 ||
- bytes.Compare(id2, key) >= 0
- }
- return bytes.Compare(id1, key) == -1 &&
- bytes.Compare(id2, key) >= 0
- }
- // Computes the offset by (n + 2^exp) % (2^mod)
- func PowerOffset(id []byte, exp int, mod int) []byte {
- // Copy the existing slice
- off := make([]byte, len(id))
- copy(off, id)
- // Convert the ID to a bigint
- idInt := big.Int{}
- idInt.SetBytes(id)
- // Get the offset
- two := big.NewInt(2)
- offset := big.Int{}
- offset.Exp(two, big.NewInt(int64(exp)), nil)
- // Sum
- sum := big.Int{}
- sum.Add(&idInt, &offset)
- // Get the ceiling
- ceil := big.Int{}
- ceil.Exp(two, big.NewInt(int64(mod)), nil)
- // Apply the mod
- idInt.Mod(&sum, &ceil)
- // Add together
- return idInt.Bytes()
- }
- // max returns the max of two ints
- func Max(a, b int) int {
- if a >= b {
- return a
- } else {
- return b
- }
- }
- // min returns the min of two ints
- func Min(a, b int) int {
- if a <= b {
- return a
- } else {
- return b
- }
- }
- // Returns the vnode nearest a key
- func NearestVnodeToKey(Vnodes []*Vnode, key []byte) *Vnode {
- for i := len(Vnodes) - 1; i >= 0; i-- {
- if bytes.Compare(Vnodes[i].Id, key) == -1 {
- return Vnodes[i]
- }
- }
- // Return the last vnode
- return Vnodes[len(Vnodes)-1]
- }
- // Merges errors together
- func MergeErrors(err1, err2 error) error {
- if err1 == nil {
- return err2
- } else if err2 == nil {
- return err1
- } else {
- return fmt.Errorf("%s\n%s", err1, err2)
- }
- }
|