-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.go
More file actions
110 lines (92 loc) · 2.93 KB
/
main.go
File metadata and controls
110 lines (92 loc) · 2.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package main
import (
"fmt"
"log"
"strings"
hashring "github.com/atharvamhaske/chash/hash-ring"
)
// DemoNode implements the CacheNode interface for demonstration
type DemoNode struct {
ID string
Data map[string]string
}
func (n *DemoNode) GetIdentifier() string {
return n.ID
}
func main() {
fmt.Println("=== Consistent Hashing Demo ===")
fmt.Println()
// Initialize hash ring with verbose logging enabled
ring := hashring.HashRingInit(hashring.EnableVerboseLogs(true))
fmt.Println("Initialized hash ring")
fmt.Println()
// Create demo nodes (representing database shards or cache servers)
node1 := &DemoNode{ID: "node-1", Data: make(map[string]string)}
node2 := &DemoNode{ID: "node-2", Data: make(map[string]string)}
node3 := &DemoNode{ID: "node-3", Data: make(map[string]string)}
// Add nodes to the hash ring
fmt.Println("Adding nodes to hash ring...")
if err := ring.AddNode(node1); err != nil {
log.Fatalf("Failed to add node1: %v", err)
}
fmt.Println("✓ Added node-1")
if err := ring.AddNode(node2); err != nil {
log.Fatalf("Failed to add node2: %v", err)
}
fmt.Println("✓ Added node-2")
if err := ring.AddNode(node3); err != nil {
log.Fatalf("Failed to add node3: %v", err)
}
fmt.Println("✓ Added node-3")
fmt.Println()
// Simulate storing keys and finding which node handles them
testKeys := []string{
"user:123",
"user:456",
"product:789",
"order:101",
"cart:202",
"session:303",
}
fmt.Println("Mapping keys to nodes:")
fmt.Println("----------------------")
for _, key := range testKeys {
node, err := ring.GetNode(key)
if err != nil {
log.Printf("Error getting node for key %s: %v", key, err)
continue
}
fmt.Printf("Key: %-15s -> Node: %s\n", key, node.GetIdentifier())
}
fmt.Println("\n" + strings.Repeat("=", 50))
fmt.Println("Demonstrating node removal...")
fmt.Println(strings.Repeat("=", 50) + "\n")
// Remove a node and show how keys are redistributed
fmt.Println("Removing node-2...")
if err := ring.RemoveNode(node2); err != nil {
log.Fatalf("Failed to remove node2: %v", err)
}
fmt.Println("✓ Removed node-2")
fmt.Println()
fmt.Println("Key mapping after node removal:")
fmt.Println("-------------------------------")
for _, key := range testKeys {
node, err := ring.GetNode(key)
if err != nil {
log.Printf("Error getting node for key %s: %v", key, err)
continue
}
fmt.Printf("Key: %-15s -> Node: %s\n", key, node.GetIdentifier())
}
fmt.Println("\n" + strings.Repeat("=", 50))
fmt.Println("Demonstrating duplicate node prevention...")
fmt.Println(strings.Repeat("=", 50) + "\n")
// Try to add a node with the same identifier
duplicateNode := &DemoNode{ID: "node-1", Data: make(map[string]string)}
if err := ring.AddNode(duplicateNode); err != nil {
fmt.Printf("✓ Correctly prevented duplicate node: %v\n", err)
}
fmt.Println("\n" + strings.Repeat("=", 50))
fmt.Println("Demo completed successfully!")
fmt.Println(strings.Repeat("=", 50))
}