github.com/balzaczyy/golucene@v0.0.0-20151210033525-d0be9ee89713/core/util/bytesref.go (about)

     1  package util
     2  
     3  // util/BytesRef.java
     4  
     5  /* An empty byte slice for convenience */
     6  var EMPTY_BYTES = []byte{}
     7  
     8  /*
     9  Represents []byte, as a slice (offset + length) into an existing
    10  []byte, similar to Go's byte slice.
    11  
    12  Important note: Unless otherwise noted, GoLucene uses []byte directly
    13  to represent terms that are encoded as UTF8 bytes in the index. It
    14  uses this class in cases when caller needs to hold a reference, while
    15  allowing underlying []byte to change.
    16  */
    17  type BytesRef struct {
    18  	// The contents of the BytesRef.
    19  	Bytes  []byte
    20  	Offset int
    21  	Length int
    22  }
    23  
    24  func NewEmptyBytesRef() *BytesRef {
    25  	return NewBytesRefFrom(EMPTY_BYTES)
    26  }
    27  
    28  func NewBytesRef(bytes []byte, offset, length int) *BytesRef {
    29  	return &BytesRef{
    30  		Bytes:  bytes,
    31  		Offset: offset,
    32  		Length: length,
    33  	}
    34  }
    35  
    36  func NewBytesRefFrom(bytes []byte) *BytesRef {
    37  	return NewBytesRef(bytes, 0, len(bytes))
    38  }
    39  
    40  /*
    41  Creates a new BytesRef that points to a copy of the bytes from
    42  other.
    43  
    44  The returned BytesRef will have a length of other.length and an
    45  offset of zero.
    46  */
    47  func DeepCopyOf(other *BytesRef) *BytesRef {
    48  	copy := NewEmptyBytesRef()
    49  	copy.copyBytes(other)
    50  	return copy
    51  }
    52  
    53  /*
    54  Expert: compares the byte against another BytesRef, returning true if
    55  the bytes are equal.
    56  */
    57  func (br *BytesRef) bytesEquals(other []byte) bool {
    58  	if br.Length != len(other) {
    59  		return false
    60  	}
    61  	for i, v := range br.ToBytes() {
    62  		if v != other[i] {
    63  			return false
    64  		}
    65  	}
    66  	return true
    67  }
    68  
    69  func (br *BytesRef) String() string {
    70  	panic("not implemented yet")
    71  }
    72  
    73  func (br *BytesRef) ToBytes() []byte {
    74  	return br.Bytes[br.Offset : br.Offset+br.Length]
    75  }
    76  
    77  /*
    78  Copies the bytes from the given BytesRef
    79  
    80  NOTE: if this would exceed the slice size, this method creates a new
    81  reference array.
    82  */
    83  func (a *BytesRef) copyBytes(other *BytesRef) {
    84  	if len(a.Bytes)-a.Offset < other.Length {
    85  		a.Bytes = make([]byte, other.Length)
    86  		a.Offset = 0
    87  	}
    88  	copy(a.Bytes, other.Bytes[other.Offset:other.Offset+other.Length])
    89  	a.Length = other.Length
    90  }
    91  
    92  func UTF8SortedAsUnicodeLess(aBytes, bBytes []byte) bool {
    93  	aLen, bLen := len(aBytes), len(bBytes)
    94  
    95  	for i, v := range aBytes {
    96  		if i >= bLen {
    97  			break
    98  		}
    99  		if v < bBytes[i] {
   100  			return true
   101  		} else if v > bBytes[i] {
   102  			return false
   103  		}
   104  	}
   105  
   106  	// One is a prefix of the other, or, they are equal:
   107  	return aLen < bLen
   108  }
   109  
   110  type BytesRefs [][]byte
   111  
   112  func (br BytesRefs) Len() int {
   113  	return len(br)
   114  }
   115  
   116  func (br BytesRefs) Less(i, j int) bool {
   117  	aBytes, bBytes := br[i], br[j]
   118  	return UTF8SortedAsUnicodeLess(aBytes, bBytes)
   119  }
   120  
   121  func (br BytesRefs) Swap(i, j int) {
   122  	br[i], br[j] = br[j], br[i]
   123  }
   124  
   125  // util/BytesRefBuilder.java
   126  
   127  type BytesRefBuilder struct {
   128  	ref *BytesRef
   129  }
   130  
   131  func NewBytesRefBuilder() *BytesRefBuilder {
   132  	return &BytesRefBuilder{
   133  		ref: NewEmptyBytesRef(),
   134  	}
   135  }
   136  
   137  /* Return a reference to the bytes of this build. */
   138  func (b *BytesRefBuilder) Bytes() []byte {
   139  	return b.ref.Bytes
   140  }
   141  
   142  /* Return the number of bytes in this buffer. */
   143  func (b *BytesRefBuilder) Length() int {
   144  	return b.ref.Length
   145  }
   146  
   147  /* Set the length. */
   148  func (b *BytesRefBuilder) SetLength(length int) {
   149  	b.ref.Length = length
   150  }
   151  
   152  /* Return the byte at the given offset. */
   153  func (b *BytesRefBuilder) At(offset int) byte {
   154  	return b.ref.Bytes[offset]
   155  }
   156  
   157  /* Set a byte. */
   158  func (b *BytesRefBuilder) Set(offset int, v byte) {
   159  	b.ref.Bytes[offset] = v
   160  }
   161  
   162  /* Ensure that this builder can hold at least capacity bytes without resizing. */
   163  func (b *BytesRefBuilder) Grow(capacity int) {
   164  	b.ref.Bytes = GrowByteSlice(b.ref.Bytes, capacity)
   165  }
   166  
   167  func (b *BytesRefBuilder) append(bytes []byte) {
   168  	b.Grow(b.ref.Length + len(bytes))
   169  	copy(b.ref.Bytes[b.ref.Length:], bytes)
   170  	b.ref.Length += len(bytes)
   171  }
   172  
   173  func (b *BytesRefBuilder) clear() {
   174  	b.SetLength(0)
   175  }
   176  
   177  func (b *BytesRefBuilder) Copy(ref []byte) {
   178  	b.clear()
   179  	b.append(ref)
   180  }
   181  
   182  func (b *BytesRefBuilder) Get() *BytesRef {
   183  	assert2(b.ref.Offset == 0, "Modifying the offset of the returned ref is illegal")
   184  	return b.ref
   185  }