Status filters for ipfs-cluster-ctl status

Optimized filter to tracker status matching by using bitwise
comparisions

License: MIT
Signed-off-by: Kishan Mohanbhai Sagathiya <kishansagathiya@gmail.com>
This commit is contained in:
Kishan Mohanbhai Sagathiya 2019-01-05 14:40:54 +05:30
parent 822c95a8d5
commit 706558cdc9
4 changed files with 55 additions and 41 deletions

View File

@ -703,14 +703,13 @@ func globalPinInfosByStatus(filter string, globalPinInfos []types.GlobalPinInfoS
if filter == "" {
return globalPinInfos
}
filters := strings.Split(strings.ToLower(filter), ",")
var filteredGlobalPinInfos []types.GlobalPinInfoSerial
for _, globalPinInfo := range globalPinInfos {
for _, pinInfo := range globalPinInfo.PeerMap {
// silenced the error because we should have detected earlier if filters were invalid
pass, _ := types.Match(filters, pinInfo.Status)
pass, _ := types.Match(filter, pinInfo.Status)
if pass {
filteredGlobalPinInfos = append(filteredGlobalPinInfos, globalPinInfo)
break

View File

@ -61,7 +61,7 @@ const (
TrackerStatusSharded
)
// Composite TrackerStatus
// Composite TrackerStatus.
const (
TrackerStatusError = TrackerStatusClusterError | TrackerStatusPinError | TrackerStatusUnpinError
TrackerStatusQueued = TrackerStatusPinQueued | TrackerStatusUnpinQueued
@ -91,13 +91,15 @@ func (st TrackerStatus) String() string {
return trackerStatusString[st]
}
// isValid checks if given tracker status is valid
func (st TrackerStatus) isValid() bool {
if st == TrackerStatusBug {
return false
}
// IsValid checks if given tracker status is valid.
func (st TrackerStatus) IsValid() bool {
return st != TrackerStatusBug
}
return true
// Match returns true if the tracker status matches the given filter.
// For example TrackerStatusPinError will match TrackerStatusPinError and TrackerStatusError
func (st TrackerStatus) Match(filter TrackerStatus) bool {
return st&filter > 0
}
// TrackerStatusFromString parses a string and returns the matching
@ -111,25 +113,18 @@ func TrackerStatusFromString(str string) TrackerStatus {
return TrackerStatusBug
}
// TrackerStatusListString returns a string containing list of all
// tracker status values
func TrackerStatusListString() string {
var list strings.Builder
counter := 0
for _, v := range trackerStatusString {
counter += (len(v) + 2)
list.WriteString(v + ", ")
if counter > 90 {
list.WriteString("\n")
counter = 0
}
// TrackerStatusAll returns a string containing list of all
// tracker status values.
func TrackerStatusAll() []TrackerStatus {
list := make([]TrackerStatus, 0)
for k := range trackerStatusString {
list = append(list, k)
}
return list.String()
return list
}
// IsFilterValid checks if given filter is valid
// IsFilterValid checks if given filter is valid.
func IsFilterValid(filter string) bool {
if filter == "" {
return true
@ -138,7 +133,7 @@ func IsFilterValid(filter string) bool {
filters := strings.Split(strings.ToLower(filter), ",")
for _, v := range filters {
if !TrackerStatusFromString(v).isValid() {
if !TrackerStatusFromString(v).IsValid() {
return false
}
}
@ -146,22 +141,30 @@ func IsFilterValid(filter string) bool {
return true
}
// Match checks if given tracker status matches with the provided filters
func Match(filters []string, status string) (bool, error) {
func toCombinedFilter(filter string) TrackerStatus {
filters := strings.Split(strings.ToLower(filter), ",")
var combinedFilter TrackerStatus
for _, v := range filters {
combinedFilter |= TrackerStatusFromString(strings.TrimSpace(v))
}
return combinedFilter
}
// Match checks if given tracker status matches with the provided filters.
func Match(filter string, status string) (bool, error) {
combinedFilter := toCombinedFilter(filter)
if !combinedFilter.IsValid() {
return false, errors.New("invalid tracker status filter value")
}
trackerStatus := TrackerStatusFromString(status)
if trackerStatus == TrackerStatusBug {
return false, errors.New("invalid tracker status string")
if !trackerStatus.IsValid() {
return false, errors.New("invalid tracker status value")
}
for _, filter := range filters {
trackerStatusFilter := TrackerStatusFromString(filter)
if trackerStatusFilter == TrackerStatusBug {
return false, errors.New("invalid tracker status filter value")
}
if trackerStatus == trackerStatusFilter {
return true, nil
}
}
return false, nil
return trackerStatus.Match(combinedFilter), nil
}
// IPFSPinStatus values

View File

@ -8,8 +8,9 @@ import (
"strings"
"time"
"github.com/ipfs/ipfs-cluster/api"
peer "github.com/libp2p/go-libp2p-peer"
"github.com/ipfs/ipfs-cluster/api"
)
func jsonFormatObject(resp interface{}) {
@ -227,3 +228,12 @@ func textFormatPrintError(obj *api.Error) {
fmt.Printf(" Code: %d\n", obj.Code)
fmt.Printf(" Message: %s\n", obj.Message)
}
func trackerStatusAllString(list []api.TrackerStatus) string {
var builder strings.Builder
for _, ts := range list {
builder.WriteString("- " + ts.String() + "\n")
}
return builder.String()
}

View File

@ -621,8 +621,10 @@ Valid filter values are tracker status types, an
alias of tracker status type ("queued" or "error"), comma separated list of
tracker status type and/or it aliases ("error,pinning"). On passing invalid
filter value will throw an error.
Full list of tracker status types includes
` + api.TrackerStatusListString(),
` + trackerStatusAllString(api.TrackerStatusAll()),
ArgsUsage: "[CID]",
Flags: []cli.Flag{
localFlag(),