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.

build.go 3.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. // Copyright (c) 2017 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. "bufio"
  17. "math"
  18. "os"
  19. "github.com/blevesearch/vellum"
  20. )
  21. const Version uint32 = 11
  22. const Type string = "zap"
  23. const fieldNotUninverted = math.MaxUint64
  24. func (sb *SegmentBase) Persist(path string) error {
  25. return PersistSegmentBase(sb, path)
  26. }
  27. // PersistSegmentBase persists SegmentBase in the zap file format.
  28. func PersistSegmentBase(sb *SegmentBase, path string) error {
  29. flag := os.O_RDWR | os.O_CREATE
  30. f, err := os.OpenFile(path, flag, 0600)
  31. if err != nil {
  32. return err
  33. }
  34. cleanup := func() {
  35. _ = f.Close()
  36. _ = os.Remove(path)
  37. }
  38. br := bufio.NewWriter(f)
  39. _, err = br.Write(sb.mem)
  40. if err != nil {
  41. cleanup()
  42. return err
  43. }
  44. err = persistFooter(sb.numDocs, sb.storedIndexOffset, sb.fieldsIndexOffset, sb.docValueOffset,
  45. sb.chunkFactor, sb.memCRC, br)
  46. if err != nil {
  47. cleanup()
  48. return err
  49. }
  50. err = br.Flush()
  51. if err != nil {
  52. cleanup()
  53. return err
  54. }
  55. err = f.Sync()
  56. if err != nil {
  57. cleanup()
  58. return err
  59. }
  60. err = f.Close()
  61. if err != nil {
  62. cleanup()
  63. return err
  64. }
  65. return nil
  66. }
  67. func persistStoredFieldValues(fieldID int,
  68. storedFieldValues [][]byte, stf []byte, spf [][]uint64,
  69. curr int, metaEncode varintEncoder, data []byte) (
  70. int, []byte, error) {
  71. for i := 0; i < len(storedFieldValues); i++ {
  72. // encode field
  73. _, err := metaEncode(uint64(fieldID))
  74. if err != nil {
  75. return 0, nil, err
  76. }
  77. // encode type
  78. _, err = metaEncode(uint64(stf[i]))
  79. if err != nil {
  80. return 0, nil, err
  81. }
  82. // encode start offset
  83. _, err = metaEncode(uint64(curr))
  84. if err != nil {
  85. return 0, nil, err
  86. }
  87. // end len
  88. _, err = metaEncode(uint64(len(storedFieldValues[i])))
  89. if err != nil {
  90. return 0, nil, err
  91. }
  92. // encode number of array pos
  93. _, err = metaEncode(uint64(len(spf[i])))
  94. if err != nil {
  95. return 0, nil, err
  96. }
  97. // encode all array positions
  98. for _, pos := range spf[i] {
  99. _, err = metaEncode(pos)
  100. if err != nil {
  101. return 0, nil, err
  102. }
  103. }
  104. data = append(data, storedFieldValues[i]...)
  105. curr += len(storedFieldValues[i])
  106. }
  107. return curr, data, nil
  108. }
  109. func InitSegmentBase(mem []byte, memCRC uint32, chunkFactor uint32,
  110. fieldsMap map[string]uint16, fieldsInv []string, numDocs uint64,
  111. storedIndexOffset uint64, fieldsIndexOffset uint64, docValueOffset uint64,
  112. dictLocs []uint64) (*SegmentBase, error) {
  113. sb := &SegmentBase{
  114. mem: mem,
  115. memCRC: memCRC,
  116. chunkFactor: chunkFactor,
  117. fieldsMap: fieldsMap,
  118. fieldsInv: fieldsInv,
  119. numDocs: numDocs,
  120. storedIndexOffset: storedIndexOffset,
  121. fieldsIndexOffset: fieldsIndexOffset,
  122. docValueOffset: docValueOffset,
  123. dictLocs: dictLocs,
  124. fieldDvReaders: make(map[uint16]*docValueReader),
  125. fieldFSTs: make(map[uint16]*vellum.FST),
  126. }
  127. sb.updateSize()
  128. err := sb.loadDvReaders()
  129. if err != nil {
  130. return nil, err
  131. }
  132. return sb, nil
  133. }