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.

dump.go 3.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. // Copyright (c) 2014 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 upsidedown
  15. import (
  16. "bytes"
  17. "sort"
  18. "github.com/blevesearch/bleve/index/store"
  19. )
  20. // the functions in this file are only intended to be used by
  21. // the bleve_dump utility and the debug http handlers
  22. // if your application relies on them, you're doing something wrong
  23. // they may change or be removed at any time
  24. func dumpPrefix(kvreader store.KVReader, rv chan interface{}, prefix []byte) {
  25. start := prefix
  26. if start == nil {
  27. start = []byte{0}
  28. }
  29. it := kvreader.PrefixIterator(start)
  30. defer func() {
  31. cerr := it.Close()
  32. if cerr != nil {
  33. rv <- cerr
  34. }
  35. }()
  36. key, val, valid := it.Current()
  37. for valid {
  38. ck := make([]byte, len(key))
  39. copy(ck, key)
  40. cv := make([]byte, len(val))
  41. copy(cv, val)
  42. row, err := ParseFromKeyValue(ck, cv)
  43. if err != nil {
  44. rv <- err
  45. return
  46. }
  47. rv <- row
  48. it.Next()
  49. key, val, valid = it.Current()
  50. }
  51. }
  52. func dumpRange(kvreader store.KVReader, rv chan interface{}, start, end []byte) {
  53. it := kvreader.RangeIterator(start, end)
  54. defer func() {
  55. cerr := it.Close()
  56. if cerr != nil {
  57. rv <- cerr
  58. }
  59. }()
  60. key, val, valid := it.Current()
  61. for valid {
  62. ck := make([]byte, len(key))
  63. copy(ck, key)
  64. cv := make([]byte, len(val))
  65. copy(cv, val)
  66. row, err := ParseFromKeyValue(ck, cv)
  67. if err != nil {
  68. rv <- err
  69. return
  70. }
  71. rv <- row
  72. it.Next()
  73. key, val, valid = it.Current()
  74. }
  75. }
  76. func (i *IndexReader) DumpAll() chan interface{} {
  77. rv := make(chan interface{})
  78. go func() {
  79. defer close(rv)
  80. dumpRange(i.kvreader, rv, nil, nil)
  81. }()
  82. return rv
  83. }
  84. func (i *IndexReader) DumpFields() chan interface{} {
  85. rv := make(chan interface{})
  86. go func() {
  87. defer close(rv)
  88. dumpPrefix(i.kvreader, rv, []byte{'f'})
  89. }()
  90. return rv
  91. }
  92. type keyset [][]byte
  93. func (k keyset) Len() int { return len(k) }
  94. func (k keyset) Swap(i, j int) { k[i], k[j] = k[j], k[i] }
  95. func (k keyset) Less(i, j int) bool { return bytes.Compare(k[i], k[j]) < 0 }
  96. // DumpDoc returns all rows in the index related to this doc id
  97. func (i *IndexReader) DumpDoc(id string) chan interface{} {
  98. idBytes := []byte(id)
  99. rv := make(chan interface{})
  100. go func() {
  101. defer close(rv)
  102. back, err := backIndexRowForDoc(i.kvreader, []byte(id))
  103. if err != nil {
  104. rv <- err
  105. return
  106. }
  107. // no such doc
  108. if back == nil {
  109. return
  110. }
  111. // build sorted list of term keys
  112. keys := make(keyset, 0)
  113. for _, entry := range back.termsEntries {
  114. for i := range entry.Terms {
  115. tfr := NewTermFrequencyRow([]byte(entry.Terms[i]), uint16(*entry.Field), idBytes, 0, 0)
  116. key := tfr.Key()
  117. keys = append(keys, key)
  118. }
  119. }
  120. sort.Sort(keys)
  121. // first add all the stored rows
  122. storedRowPrefix := NewStoredRow(idBytes, 0, []uint64{}, 'x', []byte{}).ScanPrefixForDoc()
  123. dumpPrefix(i.kvreader, rv, storedRowPrefix)
  124. // now walk term keys in order and add them as well
  125. if len(keys) > 0 {
  126. it := i.kvreader.RangeIterator(keys[0], nil)
  127. defer func() {
  128. cerr := it.Close()
  129. if cerr != nil {
  130. rv <- cerr
  131. }
  132. }()
  133. for _, key := range keys {
  134. it.Seek(key)
  135. rkey, rval, valid := it.Current()
  136. if !valid {
  137. break
  138. }
  139. rck := make([]byte, len(rkey))
  140. copy(rck, key)
  141. rcv := make([]byte, len(rval))
  142. copy(rcv, rval)
  143. row, err := ParseFromKeyValue(rck, rcv)
  144. if err != nil {
  145. rv <- err
  146. return
  147. }
  148. rv <- row
  149. }
  150. }
  151. }()
  152. return rv
  153. }