github.com/m3db/m3@v1.5.0/src/cmd/services/m3coordinator/ingest/carbon/rewrite.go (about)

     1  // Copyright (c) 2020 Uber Technologies, Inc.
     2  //
     3  // Permission is hereby granted, free of charge, to any person obtaining a copy
     4  // of this software and associated documentation files (the "Software"), to deal
     5  // in the Software without restriction, including without limitation the rights
     6  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     7  // copies of the Software, and to permit persons to whom the Software is
     8  // furnished to do so, subject to the following conditions:
     9  //
    10  // The above copyright notice and this permission notice shall be included in
    11  // all copies or substantial portions of the Software.
    12  //
    13  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    14  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    15  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    16  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    17  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    18  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    19  // THE SOFTWARE.
    20  
    21  package ingestcarbon
    22  
    23  import (
    24  	"github.com/m3db/m3/src/cmd/services/m3query/config"
    25  )
    26  
    27  // nolint: gocyclo
    28  func copyAndRewrite(
    29  	dst, src []byte,
    30  	cfg *config.CarbonIngesterRewriteConfiguration,
    31  ) []byte {
    32  	if cfg == nil || !cfg.Cleanup {
    33  		// No rewrite required.
    34  		return append(dst[:0], src...)
    35  	}
    36  
    37  	// Copy into dst as we rewrite.
    38  	dst = dst[:0]
    39  	leadingDots := true
    40  	numDots := 0
    41  	for _, c := range src {
    42  		if c == '.' {
    43  			numDots++
    44  		} else {
    45  			numDots = 0
    46  			leadingDots = false
    47  		}
    48  
    49  		if leadingDots {
    50  			// Currently processing leading dots.
    51  			continue
    52  		}
    53  
    54  		if numDots > 1 {
    55  			// Do not keep multiple dots.
    56  			continue
    57  		}
    58  
    59  		if !(c >= 'a' && c <= 'z') &&
    60  			!(c >= 'A' && c <= 'Z') &&
    61  			!(c >= '0' && c <= '9') &&
    62  			c != '.' &&
    63  			c != '-' &&
    64  			c != '_' &&
    65  			c != ':' &&
    66  			c != '#' {
    67  			// Invalid character, replace with underscore.
    68  			if n := len(dst); n > 0 && dst[n-1] == '_' {
    69  				// Preceding character already underscore.
    70  				continue
    71  			}
    72  			dst = append(dst, '_')
    73  			continue
    74  		}
    75  
    76  		// Valid character and not proceeding dot or multiple dots.
    77  		dst = append(dst, c)
    78  	}
    79  	for i := len(dst) - 1; i >= 0; i-- {
    80  		if dst[i] != '.' {
    81  			// Found non dot.
    82  			break
    83  		}
    84  		// Remove trailing dot.
    85  		dst = dst[:i]
    86  	}
    87  	return dst
    88  }