github.com/timstclair/heapster@v0.20.0-alpha1/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("m", bePair{10, -3})
    87  	sh.decSuffixes.addSuffix("", bePair{10, 0})
    88  	sh.decSuffixes.addSuffix("k", bePair{10, 3})
    89  	sh.decSuffixes.addSuffix("M", bePair{10, 6})
    90  	sh.decSuffixes.addSuffix("G", bePair{10, 9})
    91  	sh.decSuffixes.addSuffix("T", bePair{10, 12})
    92  	sh.decSuffixes.addSuffix("P", bePair{10, 15})
    93  	sh.decSuffixes.addSuffix("E", bePair{10, 18})
    94  
    95  	return sh
    96  }
    97  
    98  func (sh *suffixHandler) construct(base, exponent int, fmt Format) (s suffix, ok bool) {
    99  	switch fmt {
   100  	case DecimalSI:
   101  		return sh.decSuffixes.construct(base, exponent)
   102  	case BinarySI:
   103  		return sh.binSuffixes.construct(base, exponent)
   104  	case DecimalExponent:
   105  		if base != 10 {
   106  			return "", false
   107  		}
   108  		if exponent == 0 {
   109  			return "", true
   110  		}
   111  		return suffix("e" + strconv.FormatInt(int64(exponent), 10)), true
   112  	}
   113  	return "", false
   114  }
   115  
   116  func (sh *suffixHandler) interpret(suffix suffix) (base, exponent int, fmt Format, ok bool) {
   117  	// Try lookup tables first
   118  	if b, e, ok := sh.decSuffixes.lookup(suffix); ok {
   119  		return b, e, DecimalSI, true
   120  	}
   121  	if b, e, ok := sh.binSuffixes.lookup(suffix); ok {
   122  		return b, e, BinarySI, true
   123  	}
   124  
   125  	if len(suffix) > 1 && (suffix[0] == 'E' || suffix[0] == 'e') {
   126  		parsed, err := strconv.ParseInt(string(suffix[1:]), 10, 64)
   127  		if err != nil {
   128  			return 0, 0, DecimalExponent, false
   129  		}
   130  		return 10, int(parsed), DecimalExponent, true
   131  	}
   132  
   133  	return 0, 0, DecimalExponent, false
   134  }