Create a gist now

Instantly share code, notes, and snippets.

@redbo /gist:7592814
Last active Dec 29, 2015

What would you like to do?
package main
import (
"fmt"
"os"
"io"
"encoding/binary"
"encoding/json"
"compress/gzip"
)
type Device struct {
Id uint `json:"id"`
Device string `json:"device"`
Ip string `json:"ip"`
Meta string `json:"meta"`
Port uint `json:"port"`
Region uint `json:"region"`
ReplicationIp string `json:"replication_ip"`
ReplicationPort uint `json:"replication_port"`
Weight float64 `json:"weight"`
Zone uint `json:"zone"`
}
type Ring struct {
Devs []Device `json:"devs"`
ReplicaCount uint `json:"replica_count"`
PartShift uint `json:"part_shift"`
replica2part2dev_id [][]uint16
}
func (r Ring) GetPartitionNodes(partition uint) ([]Device) {
var response []Device
for i := uint(0); i < r.ReplicaCount ; i++ {
response = append(response, r.Devs[r.replica2part2dev_id[i][partition]])
}
return response
}
func LoadRing(path string) (Ring) {
fp, _ := os.Open(path)
gz, _ := gzip.NewReader(fp)
magic_buf := make([]byte, 4)
io.ReadFull(gz, magic_buf)
// TODO: assert magic_buf == "R1NG"
var ring_version uint16
binary.Read(gz, binary.BigEndian, &ring_version)
// TODO: assert ring_version == 1
var json_len uint32
binary.Read(gz, binary.BigEndian, &json_len)
json_buf := make([]byte, json_len)
io.ReadFull(gz, json_buf)
var ring Ring
json.Unmarshal(json_buf, &ring)
partition_count := 1 << (32 - ring.PartShift)
for i := uint(0); i < ring.ReplicaCount; i++ {
part2dev := make([]uint16, partition_count)
binary.Read(gz, binary.LittleEndian, &part2dev)
ring.replica2part2dev_id = append(ring.replica2part2dev_id, part2dev)
}
return ring
}
func main() {
ring := LoadRing("/etc/swift/object.ring.gz")
fmt.Println(ring.GetPartitionNodes(25))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment