github.com/aclisp/heapster@v0.19.2-0.20160613100040-51756f899a96/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/resource/suffix.go (about) 1 /* 2 Copyright 2014 The Kubernetes Authors All rights reserved. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package resource 18 19 import ( 20 "strconv" 21 ) 22 23 type suffix string 24 25 // suffixer can interpret and construct suffixes. 26 type suffixer interface { 27 interpret(suffix) (base, exponent int, fmt Format, ok bool) 28 construct(base, exponent int, fmt Format) (s suffix, ok bool) 29 } 30 31 // quantitySuffixer handles suffixes for all three formats that quantity 32 // can handle. 33 var quantitySuffixer = newSuffixer() 34 35 type bePair struct { 36 base, exponent int 37 } 38 39 type listSuffixer struct { 40 suffixToBE map[suffix]bePair 41 beToSuffix map[bePair]suffix 42 } 43 44 func (ls *listSuffixer) addSuffix(s suffix, pair bePair) { 45 if ls.suffixToBE == nil { 46 ls.suffixToBE = map[suffix]bePair{} 47 } 48 if ls.beToSuffix == nil { 49 ls.beToSuffix = map[bePair]suffix{} 50 } 51 ls.suffixToBE[s] = pair 52 ls.beToSuffix[pair] = s 53 } 54 55 func (ls *listSuffixer) lookup(s suffix) (base, exponent int, ok bool) { 56 pair, ok := ls.suffixToBE[s] 57 if !ok { 58 return 0, 0, false 59 } 60 return pair.base, pair.exponent, true 61 } 62 63 func (ls *listSuffixer) construct(base, exponent int) (s suffix, ok bool) { 64 s, ok = ls.beToSuffix[bePair{base, exponent}] 65 return 66 } 67 68 type suffixHandler struct { 69 decSuffixes listSuffixer 70 binSuffixes listSuffixer 71 } 72 73 func newSuffixer() suffixer { 74 sh := &suffixHandler{} 75 76 sh.binSuffixes.addSuffix("Ki", bePair{2, 10}) 77 sh.binSuffixes.addSuffix("Mi", bePair{2, 20}) 78 sh.binSuffixes.addSuffix("Gi", bePair{2, 30}) 79 sh.binSuffixes.addSuffix("Ti", bePair{2, 40}) 80 sh.binSuffixes.addSuffix("Pi", bePair{2, 50}) 81 sh.binSuffixes.addSuffix("Ei", bePair{2, 60}) 82 // Don't emit an error when trying to produce 83 // a suffix for 2^0. 84 sh.decSuffixes.addSuffix("", bePair{2, 0}) 85 86 sh.decSuffixes.addSuffix("n", bePair{10, -9}) 87 sh.decSuffixes.addSuffix("u", bePair{10, -6}) 88 sh.decSuffixes.addSuffix("m", bePair{10, -3}) 89 sh.decSuffixes.addSuffix("", bePair{10, 0}) 90 sh.decSuffixes.addSuffix("k", bePair{10, 3}) 91 sh.decSuffixes.addSuffix("M", bePair{10, 6}) 92 sh.decSuffixes.addSuffix("G", bePair{10, 9}) 93 sh.decSuffixes.addSuffix("T", bePair{10, 12}) 94 sh.decSuffixes.addSuffix("P", bePair{10, 15}) 95 sh.decSuffixes.addSuffix("E", bePair{10, 18}) 96 97 return sh 98 } 99 100 func (sh *suffixHandler) construct(base, exponent int, fmt Format) (s suffix, ok bool) { 101 switch fmt { 102 case DecimalSI: 103 return sh.decSuffixes.construct(base, exponent) 104 case BinarySI: 105 return sh.binSuffixes.construct(base, exponent) 106 case DecimalExponent: 107 if base != 10 { 108 return "", false 109 } 110 if exponent == 0 { 111 return "", true 112 } 113 return suffix("e" + strconv.FormatInt(int64(exponent), 10)), true 114 } 115 return "", false 116 } 117 118 func (sh *suffixHandler) interpret(suffix suffix) (base, exponent int, fmt Format, ok bool) { 119 // Try lookup tables first 120 if b, e, ok := sh.decSuffixes.lookup(suffix); ok { 121 return b, e, DecimalSI, true 122 } 123 if b, e, ok := sh.binSuffixes.lookup(suffix); ok { 124 return b, e, BinarySI, true 125 } 126 127 if len(suffix) > 1 && (suffix[0] == 'E' || suffix[0] == 'e') { 128 parsed, err := strconv.ParseInt(string(suffix[1:]), 10, 64) 129 if err != nil { 130 return 0, 0, DecimalExponent, false 131 } 132 return 10, int(parsed), DecimalExponent, true 133 } 134 135 return 0, 0, DecimalExponent, false 136 }