You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

118 lines
2.9 KiB

  1. // Copyright (c) 2019 Couchbase, Inc.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package zap
  15. import (
  16. "encoding/binary"
  17. "fmt"
  18. "github.com/blevesearch/bleve/index/scorch/segment"
  19. )
  20. type chunkedIntDecoder struct {
  21. startOffset uint64
  22. dataStartOffset uint64
  23. chunkOffsets []uint64
  24. curChunkBytes []byte
  25. data []byte
  26. r *segment.MemUvarintReader
  27. }
  28. // newChunkedIntDecoder expects an optional or reset chunkedIntDecoder for better reuse.
  29. func newChunkedIntDecoder(buf []byte, offset uint64, rv *chunkedIntDecoder) *chunkedIntDecoder {
  30. if rv == nil {
  31. rv = &chunkedIntDecoder{startOffset: offset, data: buf}
  32. } else {
  33. rv.startOffset = offset
  34. rv.data = buf
  35. }
  36. var n, numChunks uint64
  37. var read int
  38. if offset == termNotEncoded {
  39. numChunks = 0
  40. } else {
  41. numChunks, read = binary.Uvarint(buf[offset+n : offset+n+binary.MaxVarintLen64])
  42. }
  43. n += uint64(read)
  44. if cap(rv.chunkOffsets) >= int(numChunks) {
  45. rv.chunkOffsets = rv.chunkOffsets[:int(numChunks)]
  46. } else {
  47. rv.chunkOffsets = make([]uint64, int(numChunks))
  48. }
  49. for i := 0; i < int(numChunks); i++ {
  50. rv.chunkOffsets[i], read = binary.Uvarint(buf[offset+n : offset+n+binary.MaxVarintLen64])
  51. n += uint64(read)
  52. }
  53. rv.dataStartOffset = offset + n
  54. return rv
  55. }
  56. func (d *chunkedIntDecoder) loadChunk(chunk int) error {
  57. if d.startOffset == termNotEncoded {
  58. d.r = segment.NewMemUvarintReader([]byte(nil))
  59. return nil
  60. }
  61. if chunk >= len(d.chunkOffsets) {
  62. return fmt.Errorf("tried to load freq chunk that doesn't exist %d/(%d)",
  63. chunk, len(d.chunkOffsets))
  64. }
  65. end, start := d.dataStartOffset, d.dataStartOffset
  66. s, e := readChunkBoundary(chunk, d.chunkOffsets)
  67. start += s
  68. end += e
  69. d.curChunkBytes = d.data[start:end]
  70. if d.r == nil {
  71. d.r = segment.NewMemUvarintReader(d.curChunkBytes)
  72. } else {
  73. d.r.Reset(d.curChunkBytes)
  74. }
  75. return nil
  76. }
  77. func (d *chunkedIntDecoder) reset() {
  78. d.startOffset = 0
  79. d.dataStartOffset = 0
  80. d.chunkOffsets = d.chunkOffsets[:0]
  81. d.curChunkBytes = d.curChunkBytes[:0]
  82. d.data = d.data[:0]
  83. if d.r != nil {
  84. d.r.Reset([]byte(nil))
  85. }
  86. }
  87. func (d *chunkedIntDecoder) isNil() bool {
  88. return d.curChunkBytes == nil || len(d.curChunkBytes) == 0
  89. }
  90. func (d *chunkedIntDecoder) readUvarint() (uint64, error) {
  91. return d.r.ReadUvarint()
  92. }
  93. func (d *chunkedIntDecoder) SkipUvarint() {
  94. d.r.SkipUvarint()
  95. }
  96. func (d *chunkedIntDecoder) SkipBytes(count int) {
  97. d.r.SkipBytes(count)
  98. }
  99. func (d *chunkedIntDecoder) Len() int {
  100. return d.r.Len()
  101. }