Skip to content

Commit fcc1387

Browse files
authored
Create ConsistentHashing.sol
```solidity // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; contract ConsistentHashing { // Virtual nodes increase distribution uint256 public constant VIRTUAL_NODES = 100; // Maps hash positions to node addresses mapping(uint256 => address) public ring; uint256[] public sortedPositions; // Add a node to the hash ring function addNode(address node) public { for (uint256 i = 0; i < VIRTUAL_NODES; i++) { // Create a unique hash for each virtual node uint256 position = uint256(keccak256(abi.encodePacked(node, i))); ring[position] = node; // Insert position into sorted array _insertSorted(position); } } // Helper to insert a position into the sorted array function _insertSorted(uint256 position) private { // Simple insertion sort sortedPositions.push(position); uint256 j = sortedPositions.length - 1; while (j > 0 && sortedPositions[j - 1] > position) { sortedPositions[j] = sortedPositions[j - 1]; j--; } sortedPositions[j] = position; } // Find the node responsible for a key function getNode(bytes calldata key) public view returns (address) { require(sortedPositions.length > 0, "No nodes available"); uint256 keyHash = uint256(keccak256(key)); // Binary search to find the first position >= keyHash uint256 left = 0; uint256 right = sortedPositions.length - 1; while (left < right) { uint256 mid = (left + right) / 2; if (sortedPositions[mid] < keyHash) { left = mid + 1; } else { right = mid; } } // If we went past the end, wrap around to the first node uint256 position; if (left == sortedPositions.length - 1 && sortedPositions[left] < keyHash) { position = sortedPositions[0]; } else { position = sortedPositions[left]; } return ring[position]; } } ```
1 parent 2b4d1cf commit fcc1387

File tree

1 file changed

+67
-0
lines changed

1 file changed

+67
-0
lines changed
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8.0;
3+
4+
contract ConsistentHashing {
5+
// Virtual nodes increase distribution
6+
uint256 public constant VIRTUAL_NODES = 100;
7+
8+
// Maps hash positions to node addresses
9+
mapping(uint256 => address) public ring;
10+
uint256[] public sortedPositions;
11+
12+
// Add a node to the hash ring
13+
function addNode(address node) public {
14+
for (uint256 i = 0; i < VIRTUAL_NODES; i++) {
15+
// Create a unique hash for each virtual node
16+
uint256 position = uint256(keccak256(abi.encodePacked(node, i)));
17+
ring[position] = node;
18+
19+
// Insert position into sorted array
20+
_insertSorted(position);
21+
}
22+
}
23+
24+
// Helper to insert a position into the sorted array
25+
function _insertSorted(uint256 position) private {
26+
// Simple insertion sort
27+
sortedPositions.push(position);
28+
uint256 j = sortedPositions.length - 1;
29+
30+
while (j > 0 && sortedPositions[j - 1] > position) {
31+
sortedPositions[j] = sortedPositions[j - 1];
32+
j--;
33+
}
34+
35+
sortedPositions[j] = position;
36+
}
37+
38+
// Find the node responsible for a key
39+
function getNode(bytes calldata key) public view returns (address) {
40+
require(sortedPositions.length > 0, "No nodes available");
41+
42+
uint256 keyHash = uint256(keccak256(key));
43+
44+
// Binary search to find the first position >= keyHash
45+
uint256 left = 0;
46+
uint256 right = sortedPositions.length - 1;
47+
48+
while (left < right) {
49+
uint256 mid = (left + right) / 2;
50+
if (sortedPositions[mid] < keyHash) {
51+
left = mid + 1;
52+
} else {
53+
right = mid;
54+
}
55+
}
56+
57+
// If we went past the end, wrap around to the first node
58+
uint256 position;
59+
if (left == sortedPositions.length - 1 && sortedPositions[left] < keyHash) {
60+
position = sortedPositions[0];
61+
} else {
62+
position = sortedPositions[left];
63+
}
64+
65+
return ring[position];
66+
}
67+
}

0 commit comments

Comments
 (0)