]> Cypherpunks.ru repositories - nncp.git/blobdiff - src/nice.go
Full go modules usage
[nncp.git] / src / nice.go
diff --git a/src/nice.go b/src/nice.go
new file mode 100644 (file)
index 0000000..eceb6fc
--- /dev/null
@@ -0,0 +1,108 @@
+package nncp
+
+import (
+       "errors"
+       "fmt"
+       "regexp"
+       "strconv"
+       "strings"
+)
+
+const (
+       NiceFlash    = 32
+       NicePriority = 96
+       NiceNormal   = 160
+       NiceBulk     = 224
+
+       DefaultNiceExec = NicePriority
+       DefaultNiceFreq = NiceNormal
+       DefaultNiceFile = NiceBulk
+)
+
+var (
+       niceRe      *regexp.Regexp   = regexp.MustCompile(`^(\w+)([-+])(\d+)$`)
+       niceAliases map[string]uint8 = map[string]uint8{
+               "flash":    NiceFlash,
+               "f":        NiceFlash,
+               "priority": NicePriority,
+               "p":        NicePriority,
+               "normal":   NiceNormal,
+               "n":        NiceNormal,
+               "bulk":     NiceBulk,
+               "b":        NiceBulk,
+               "max":      255,
+       }
+)
+
+func NicenessParse(s string) (uint8, error) {
+       if nice, err := strconv.Atoi(s); err == nil {
+               if nice <= 0 || nice > 255 {
+                       return 0, errors.New("nice out of bounds")
+               }
+               return uint8(nice), nil
+       }
+       s = strings.ToLower(s)
+       var baseNice uint8
+       var found bool
+       if baseNice, found = niceAliases[s]; found {
+               return baseNice, nil
+       }
+       matches := niceRe.FindStringSubmatch(s)
+       if len(matches) != 1+3 {
+               return 0, errors.New("invalid niceness")
+       }
+       baseNice, found = niceAliases[matches[1]]
+       if !found {
+               return 0, errors.New("invalid niceness")
+       }
+       delta, err := strconv.Atoi(matches[3])
+       if err != nil {
+               return 0, err
+       }
+       if matches[2] == "-" {
+               if delta > 31 {
+                       return 0, errors.New("too big niceness delta")
+               }
+               return baseNice - uint8(delta), nil
+       } else {
+               if delta > 32 || (baseNice == NiceBulk && delta > 31) {
+                       return 0, errors.New("too big niceness delta")
+               }
+               return baseNice + uint8(delta), nil
+       }
+}
+
+func NicenessFmt(nice uint8) string {
+       switch {
+       case nice == 255:
+               return "MAX"
+       case NiceFlash-31 < nice && nice < NiceFlash:
+               return fmt.Sprintf("F-%d", NiceFlash-nice)
+       case nice == NiceFlash:
+               return "F"
+       case NiceFlash < nice && nice <= (NiceFlash+32):
+               return fmt.Sprintf("F+%d", nice-NiceFlash)
+
+       case NicePriority-31 < nice && nice < NicePriority:
+               return fmt.Sprintf("P-%d", NicePriority-nice)
+       case nice == NicePriority:
+               return "P"
+       case NicePriority < nice && nice <= (NicePriority+32):
+               return fmt.Sprintf("P+%d", nice-NicePriority)
+
+       case NiceNormal-31 < nice && nice < NiceNormal:
+               return fmt.Sprintf("N-%d", NiceNormal-nice)
+       case nice == NiceNormal:
+               return "N"
+       case NiceNormal < nice && nice <= (NiceNormal+32):
+               return fmt.Sprintf("N+%d", nice-NiceNormal)
+
+       case NiceBulk-31 < nice && nice < NiceBulk:
+               return fmt.Sprintf("B-%d", NiceBulk-nice)
+       case nice == NiceBulk:
+               return "B"
+       case NiceBulk < nice && nice <= (NiceBulk+30):
+               return fmt.Sprintf("B+%d", nice-NiceBulk)
+       }
+       return strconv.Itoa(int(nice))
+}