github.com/go-graphite/carbonapi@v0.17.0/expr/types/extract.go (about)

     1  package types
     2  
     3  import (
     4  	"strings"
     5  	"unicode/utf8"
     6  )
     7  
     8  var allowedCharactersInMetricName = map[byte]struct{}{
     9  	'=': struct{}{},
    10  	'@': struct{}{},
    11  }
    12  
    13  func byteAllowedInName(b byte) bool {
    14  	_, ok := allowedCharactersInMetricName[b]
    15  	return ok
    16  }
    17  
    18  // ExtractNameLoc extracts name start:end location out of function list with . Only for use in MetrciData name parse, it's has more allowed chard in names, like =
    19  func ExtractNameLoc(s string) (int, int) {
    20  	// search for a metric name in 's'
    21  	// metric name is defined to be a Series of name characters terminated by a ',' or ')'
    22  
    23  	var w, i, start, braces int
    24  	var c rune
    25  FOR:
    26  	for i, c = range s {
    27  		w = i
    28  		switch c {
    29  		case '{':
    30  			braces++
    31  		case '}':
    32  			if braces == 0 {
    33  				break FOR
    34  			}
    35  			braces--
    36  		case ',':
    37  			if braces == 0 {
    38  				break FOR
    39  			}
    40  		case '(':
    41  			if i >= 11 {
    42  				n := i - 11
    43  				if s[n:i] == "seriesByTag" {
    44  					end := strings.IndexRune(s[n:], ')')
    45  					if end == -1 {
    46  						return n, len(s) // broken end of args, can't exist in correctly parsed functions
    47  					} else {
    48  						return n, n + end + 1
    49  					}
    50  				}
    51  			}
    52  			start = i + 1
    53  		case ')':
    54  			break FOR
    55  		}
    56  		w += utf8.RuneLen(c)
    57  	}
    58  
    59  	return start, w
    60  }
    61  
    62  // ExtractName extracts name out of function list. Only for use in MetrciData name parse, it's has more allowed chard in names, like =
    63  func ExtractName(s string) string {
    64  	start, end := ExtractNameLoc(s)
    65  	return s[start:end]
    66  }
    67  
    68  // ExtractNameTag extracts name tag out of function list with . Only for use in MetrciData name parse, it's has more allowed chard in names, like =
    69  func ExtractNameTag(s string) string {
    70  	// search for a metric name in 's'
    71  	// metric name is defined to be a Series of name characters terminated by a ',' or ')'
    72  
    73  	var w, i, start, braces int
    74  	var c rune
    75  FOR:
    76  	for i, c = range s {
    77  		w = i
    78  		switch c {
    79  		case '{':
    80  			braces++
    81  		case '}':
    82  			if braces == 0 {
    83  				break FOR
    84  			}
    85  			braces--
    86  		case ',':
    87  			if braces == 0 {
    88  				break FOR
    89  			}
    90  		case '(':
    91  			if i >= 11 {
    92  				n := i - 11
    93  				if s[n:i] == "seriesByTag" {
    94  					end := strings.IndexRune(s[n:], ')')
    95  					if end == -1 {
    96  						return s[n:len(s)] // broken end of args, can't exist in correctly parsed functions
    97  					} else {
    98  						return s[n : n+end+1]
    99  					}
   100  				}
   101  			}
   102  			start = i + 1
   103  		case ')', ';':
   104  			break FOR
   105  		}
   106  		w += utf8.RuneLen(c)
   107  	}
   108  
   109  	return s[start:w]
   110  }