123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384 |
- package chord
- import (
- "fmt"
- "math/big"
- "trial/achord/models"
- )
- type fingerTable []*fingerEntry
- func newFingerTable(node *models.Node, m int) fingerTable {
- ft := make([]*fingerEntry, m)
- for i := range ft {
- ft[i] = newFingerEntry(fingerID(node.Id, i, m), node)
- }
- return ft
- }
- // fingerEntry represents a single finger table entry
- type fingerEntry struct {
- Id []byte // ID hash of (n + 2^i) mod (2^m)
- Node *models.Node // RemoteNode that Start points to
- }
- // newFingerEntry returns an allocated new finger entry with the attributes set
- func newFingerEntry(id []byte, node *models.Node) *fingerEntry {
- return &fingerEntry{
- Id: id,
- Node: node,
- }
- }
- // Computes the offset by (n + 2^i) mod (2^m)
- func fingerID(n []byte, i int, m int) []byte {
- // Convert the ID to a bigint
- idInt := (&big.Int{}).SetBytes(n)
- // Get the offset
- two := big.NewInt(2)
- offset := big.Int{}
- offset.Exp(two, big.NewInt(int64(i)), nil)
- // Sum
- sum := big.Int{}
- sum.Add(idInt, &offset)
- // Get the ceiling
- ceil := big.Int{}
- ceil.Exp(two, big.NewInt(int64(m)), nil)
- // Apply the mod
- idInt.Mod(&sum, &ceil)
- // Add together
- return idInt.Bytes()
- }
- // called periodically. refreshes finger table entries.
- // next stores the index of the next finger to fix.
- func (n *Node) fixFinger(next int) int {
- nextHash := fingerID(n.Id, next, n.cnf.HashSize)
- succ, err := n.findSuccessor(nextHash)
- nextNum := (next + 1) % n.cnf.HashSize
- if err != nil || succ == nil {
- fmt.Println("error: ", err, succ)
- fmt.Printf("finger lookup failed %x %x \n", n.Id, nextHash)
- // TODO: Check how to handle retry, passing ahead for now
- return nextNum
- }
- finger := newFingerEntry(nextHash, succ)
- n.ftMtx.Lock()
- n.fingerTable[next] = finger
- // aInt := (&big.Int{}).SetBytes(nextHash)
- // bInt := (&big.Int{}).SetBytes(finger.Node.Id)
- // fmt.Printf("finger entry %d, %d,%d\n", next, aInt, bInt)
- n.ftMtx.Unlock()
- return nextNum
- }
|