github.com/m3db/m3@v1.5.0/src/x/serialize/fake_encoder.go (about)

     1  // Copyright (c) 2021 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 serialize
    22  
    23  import (
    24  	"bytes"
    25  	"errors"
    26  	"fmt"
    27  
    28  	"github.com/m3db/m3/src/metrics/metric/id"
    29  	"github.com/m3db/m3/src/x/checked"
    30  	"github.com/m3db/m3/src/x/ident"
    31  )
    32  
    33  // FakeTagEncoder is a fake TagEncoder for testing.
    34  // It encodes a set of TagPair as name1#value1#name2#value#...
    35  type FakeTagEncoder struct {
    36  	data []byte
    37  }
    38  
    39  // Decode the encoded data back into a set of TagPairs.
    40  func (f *FakeTagEncoder) Decode() []id.TagPair {
    41  	tags := make([]id.TagPair, 0)
    42  	parts := bytes.Split(f.data[0:len(f.data)-1], []byte{'#'})
    43  	for i := 0; i < len(parts); i += 2 {
    44  		tags = append(tags, id.TagPair{
    45  			Name:  parts[i],
    46  			Value: parts[i+1],
    47  		})
    48  	}
    49  	return tags
    50  }
    51  
    52  // Encode the tags. The original tags can be retrieved with Decode for testing.
    53  func (f *FakeTagEncoder) Encode(tags ident.TagIterator) error {
    54  	if len(f.data) > 0 {
    55  		return errors.New("must call Reset if reusing the fake encoder")
    56  	}
    57  	for tags.Next() {
    58  		cur := tags.Current()
    59  		if err := checkValue(cur.Name.Bytes()); err != nil {
    60  			return err
    61  		}
    62  		if err := checkValue(cur.Value.Bytes()); err != nil {
    63  			return err
    64  		}
    65  		f.data = append(f.data, cur.Name.Bytes()...)
    66  		f.data = append(f.data, '#')
    67  		f.data = append(f.data, cur.Value.Bytes()...)
    68  		f.data = append(f.data, '#')
    69  	}
    70  	return nil
    71  }
    72  
    73  func checkValue(v []byte) error {
    74  	if bytes.Contains(v, []byte{'#'}) {
    75  		return fmt.Errorf("%v cannot contain a #", v)
    76  	}
    77  	return nil
    78  }
    79  
    80  // Data gets the encoded tags.
    81  func (f *FakeTagEncoder) Data() (checked.Bytes, bool) {
    82  	b := checked.NewBytes(f.data, nil)
    83  	b.IncRef()
    84  	return b, true
    85  }
    86  
    87  // Reset the stored encoded data.
    88  func (f *FakeTagEncoder) Reset() {
    89  	f.data = f.data[:0]
    90  }
    91  
    92  // Finalize does nothing.
    93  func (f *FakeTagEncoder) Finalize() {
    94  }
    95  
    96  var _ TagEncoder = &FakeTagEncoder{}