github.com/GuanceCloud/cliutils@v1.1.21/pprofparser/domain/quantity/unit.go (about) 1 package quantity 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "strings" 7 "time" 8 ) 9 10 var ( 11 MemoryDisplayName = "digital" 12 MemoryDefaultUnitFlag = "B" 13 14 DurationDisplayName = "time" 15 DurationDefaultUnitFlag = "μs" 16 ) 17 18 var UnknownUnit = &Unit{Kind: UnknownKind, Name: "unknown"} 19 20 var ( 21 NanoSecond = &Unit{Kind: Duration, Base: int64(time.Nanosecond), Name: "ns"} 22 MicroSecond = &Unit{Kind: Duration, Base: int64(time.Microsecond), Name: "us"} 23 MilliSecond = &Unit{Kind: Duration, Base: int64(time.Millisecond), Name: "ms"} 24 Second = &Unit{Kind: Duration, Base: int64(time.Second), Name: "s"} 25 Minute = &Unit{Kind: Duration, Base: int64(time.Minute), Name: "m"} 26 Hour = &Unit{Kind: Duration, Base: int64(time.Hour), Name: "h"} 27 ) 28 29 var ( 30 CountUnit = &Unit{Kind: Count, Base: 1, Name: ""} 31 ) 32 33 var ( 34 Byte = &Unit{Kind: Memory, Base: 1, Name: "Bytes"} 35 KiloByte = &Unit{Kind: Memory, Base: 1 << 10, Name: "KB"} 36 MegaByte = &Unit{Kind: Memory, Base: 1 << 20, Name: "MB"} 37 GigaByte = &Unit{Kind: Memory, Base: 1 << 30, Name: "GB"} 38 TeraByte = &Unit{Kind: Memory, Base: 1 << 40, Name: "TB"} 39 PetaByte = &Unit{Kind: Memory, Base: 1 << 50, Name: "PB"} 40 ) 41 42 var ( 43 memoryUnitMaps = map[string]*Unit{ 44 "bytes": Byte, 45 "byte": Byte, 46 "b": Byte, 47 48 "kilobytes": KiloByte, 49 "kilobyte": KiloByte, // 1000 50 "kibibytes": KiloByte, 51 "kibibyte": KiloByte, // 1024 52 "kib": KiloByte, 53 "kb": KiloByte, 54 55 "megabytes": MegaByte, 56 "megabyte": MegaByte, 57 "megibytes": MegaByte, 58 "megibyte": MegaByte, 59 "mib": MegaByte, 60 "mb": MegaByte, 61 62 "gigabytes": GigaByte, 63 "gigabyte": GigaByte, 64 "gigibytes": GigaByte, 65 "gigibyte": GigaByte, 66 "gib": GigaByte, 67 "gb": GigaByte, 68 69 "terabytes": TeraByte, 70 "terabyte": TeraByte, 71 "tebibytes": TeraByte, 72 "tebibyte": TeraByte, 73 "trillionbytes": TeraByte, 74 "trillionbyte": TeraByte, 75 "tib": TeraByte, 76 "tb": TeraByte, 77 78 "petabytes": PetaByte, 79 "petabyte": PetaByte, 80 "pebibytes": PetaByte, 81 "pebibyte": PetaByte, 82 "pib": PetaByte, 83 "pb": PetaByte, 84 } 85 86 durationUnitMaps = map[string]*Unit{ 87 "nanoseconds": NanoSecond, 88 "nanosecond": NanoSecond, 89 "ns": NanoSecond, 90 91 "microseconds": MicroSecond, 92 "microsecond": MicroSecond, 93 "us": MicroSecond, 94 "µs": MicroSecond, 95 96 "milliseconds": MilliSecond, 97 "millisecond": MilliSecond, 98 "ms": MilliSecond, 99 100 "seconds": Second, 101 "second": Second, 102 "s": Second, 103 104 "minutes": Minute, 105 "minute": Minute, 106 "m": Minute, 107 108 "hours": Hour, 109 "hour": Hour, 110 "h": Hour, 111 } 112 ) 113 114 type Unit struct { 115 Kind *Kind 116 Base int64 117 Name string 118 } 119 120 func (u *Unit) String() string { 121 return u.Name 122 } 123 124 // ConvertTo convert value for Unit u to Unit target 125 func (u *Unit) ConvertTo(target *Unit, value int64) (int64, error) { 126 if u.Kind != target.Kind { 127 return 0, fmt.Errorf("unit kinds are not compatiable") 128 } 129 return value * u.Base / target.Base, nil 130 } 131 132 // ConvertToDefaultUnit convert value in Unit u to Unit Kind's default unit 133 func (u *Unit) ConvertToDefaultUnit(value int64) int64 { 134 v, _ := u.ConvertTo(u.Kind.DefaultUnit, value) 135 return v 136 } 137 138 func (u *Unit) Quantity(v int64) *Quantity { 139 return &Quantity{ 140 Unit: u, 141 Value: v, 142 } 143 } 144 145 func (u *Unit) MarshalJSON() ([]byte, error) { 146 var flags []string 147 148 switch u.Kind { 149 case Memory: 150 flags = []string{MemoryDisplayName, MemoryDefaultUnitFlag} 151 case Duration: 152 flags = []string{DurationDisplayName, DurationDefaultUnitFlag} 153 default: 154 flags = make([]string, 0) 155 } 156 return json.Marshal(flags) 157 } 158 159 func parseDuration(s string) (*Unit, error) { 160 unit := strings.ToLower(strings.TrimSpace(s)) 161 if u, ok := durationUnitMaps[unit]; ok { 162 return u, nil 163 } 164 switch { 165 case strings.HasPrefix(unit, "na"): // nano 166 return NanoSecond, nil 167 case strings.HasPrefix(unit, "mic"): // micro 168 return MicroSecond, nil 169 case strings.HasPrefix(unit, "mil"): // milli 170 return MilliSecond, nil 171 case strings.HasPrefix(unit, "min"): // minute 172 return Minute, nil 173 case strings.HasPrefix(unit, "hour"): // hour 174 return Hour, nil 175 case strings.HasPrefix(unit, "sec"): // second 176 return Second, nil 177 } 178 return nil, fmt.Errorf("can not resolve duration unit from [%s]", s) 179 } 180 181 func parseMemoryUnit(s string) (*Unit, error) { 182 unit := strings.ToLower(strings.TrimSpace(s)) 183 if u, ok := memoryUnitMaps[unit]; ok { 184 return u, nil 185 } 186 switch { 187 case strings.HasPrefix(unit, "k"): 188 return KiloByte, nil 189 case strings.HasPrefix(unit, "m"): 190 return MegaByte, nil 191 case strings.HasPrefix(unit, "g"): 192 return GigaByte, nil 193 case strings.HasPrefix(unit, "t"): 194 return TeraByte, nil 195 case strings.HasPrefix(unit, "p"): 196 return PetaByte, nil 197 case strings.HasPrefix(unit, "byte"): 198 return Byte, nil 199 } 200 return nil, fmt.Errorf("can not resolve memory unit from [%s]", s) 201 } 202 203 func ParseUnit(kind *Kind, s string) (*Unit, error) { 204 switch kind { 205 case Count: 206 return CountUnit, nil 207 case Memory: 208 return parseMemoryUnit(s) 209 case Duration: 210 return parseDuration(s) 211 } 212 return nil, fmt.Errorf("unknown quantity kind") 213 }