func mainCmd(r ring.Ring, b *ring.Builder) error { if r != nil { // TODO: // Version Info (the value as well as the time translation) // Number of tier levels // Replica count // Indication of how risky the assignments are: // Replicas not in distinct tiers, nodes s := r.Stats() report := [][]string{ []string{brimtext.ThousandsSep(int64(s.PartitionCount), ","), "Partitions"}, []string{brimtext.ThousandsSep(int64(s.PartitionBitCount), ","), "Partition Bits"}, []string{brimtext.ThousandsSep(int64(s.NodeCount), ","), "Nodes"}, []string{brimtext.ThousandsSep(int64(s.InactiveNodeCount), ","), "Inactive Nodes"}, []string{brimtext.ThousandsSepU(s.TotalCapacity, ","), "Total Node Capacity"}, []string{fmt.Sprintf("%.02f%%", s.MaxUnderNodePercentage), fmt.Sprintf("Worst Underweight Node (ID %016x)", s.MaxUnderNodeID)}, []string{fmt.Sprintf("%.02f%%", s.MaxOverNodePercentage), fmt.Sprintf("Worst Overweight Node (ID %016x)", s.MaxOverNodeID)}, } reportOpts := brimtext.NewDefaultAlignOptions() reportOpts.Alignments = []brimtext.Alignment{brimtext.Right, brimtext.Left} fmt.Print(brimtext.Align(report, reportOpts)) } if b != nil { // TODO: // Inactive node count // Total capacity report := [][]string{ []string{brimtext.ThousandsSep(int64(len(b.Nodes())), ","), "Nodes"}, []string{brimtext.ThousandsSep(int64(b.ReplicaCount()), ","), "Replicas"}, []string{brimtext.ThousandsSep(int64(b.PointsAllowed()), ","), "Points Allowed"}, []string{brimtext.ThousandsSep(int64(b.MaxPartitionBitCount()), ","), "Max Partition Bits"}, []string{brimtext.ThousandsSep(int64(b.MoveWait()), ","), "Move Wait"}, } reportOpts := brimtext.NewDefaultAlignOptions() reportOpts.Alignments = []brimtext.Alignment{brimtext.Right, brimtext.Left} fmt.Print(brimtext.Align(report, reportOpts)) return nil } return nil }
func nodeCmd(r ring.Ring, b *ring.Builder, args []string, full bool) (changed bool, err error) { var nodes ring.NodeSlice if r != nil { nodes = r.Nodes() } else { bnodes := b.Nodes() nodes = make(ring.NodeSlice, len(bnodes)) for i := len(nodes) - 1; i >= 0; i-- { nodes[i] = bnodes[i] } } filterArgs := make([]string, 0) setArgs := make([]string, 0) setFound := false for _, arg := range args { if arg == "set" { setFound = true continue } if setFound { setArgs = append(setArgs, arg) } else { filterArgs = append(filterArgs, arg) } } if len(setArgs) > 0 && b == nil { err = fmt.Errorf("set is only valid for builder files") return } if nodes, err = nodes.Filter(filterArgs); err != nil { return } if len(nodes) > 0 && len(setArgs) > 0 { for _, n := range nodes { if err = addOrSetCmd(r, b, setArgs, n.(ring.BuilderNode)); err != nil { return } changed = true } } if full || len(nodes) == 1 { first := true for _, n := range nodes { if first { first = false } else { fmt.Println() } report := [][]string{ []string{"ID:", fmt.Sprintf("%016x", n.ID())}, []string{"Active:", fmt.Sprintf("%v", n.Active())}, []string{"Capacity:", fmt.Sprintf("%d", n.Capacity())}, []string{"Tiers:", strings.Join(n.Tiers(), "\n")}, []string{"Addresses:", strings.Join(n.Addresses(), "\n")}, []string{"Meta:", n.Meta()}, } fmt.Print(brimtext.Align(report, nil)) } return } header := []string{ "ID", "Active", "Capacity", "Address", "Meta", } report := [][]string{header} reportAlign := brimtext.NewDefaultAlignOptions() reportAlign.Alignments = []brimtext.Alignment{ brimtext.Left, brimtext.Right, brimtext.Right, brimtext.Right, brimtext.Left, } reportLine := func(n ring.Node) []string { return []string{ fmt.Sprintf("%016x", n.ID()), fmt.Sprintf("%v", n.Active()), fmt.Sprintf("%d", n.Capacity()), n.Address(0), n.Meta(), } } for _, n := range nodes { if n.Active() { report = append(report, reportLine(n)) } } for _, n := range nodes { if !n.Active() { report = append(report, reportLine(n)) } } fmt.Print(brimtext.Align(report, reportAlign)) return }