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  }