mirror of
				https://github.com/go-gitea/gitea
				synced 2025-10-31 03:18:24 +00:00 
			
		
		
		
	* Improve issue indexer * Fix new issue sqlite bug * Different test indexer paths for each db * Add integration indexer paths to make clean
		
			
				
	
	
		
			175 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			175 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| //  Copyright (c) 2014 Couchbase, Inc.
 | |
| //
 | |
| // Licensed under the Apache License, Version 2.0 (the "License");
 | |
| // you may not use this file except in compliance with the License.
 | |
| // You may obtain a copy of the License at
 | |
| //
 | |
| // 		http://www.apache.org/licenses/LICENSE-2.0
 | |
| //
 | |
| // Unless required by applicable law or agreed to in writing, software
 | |
| // distributed under the License is distributed on an "AS IS" BASIS,
 | |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | |
| // See the License for the specific language governing permissions and
 | |
| // limitations under the License.
 | |
| 
 | |
| package upsidedown
 | |
| 
 | |
| import (
 | |
| 	"bytes"
 | |
| 	"sort"
 | |
| 
 | |
| 	"github.com/blevesearch/bleve/index/store"
 | |
| )
 | |
| 
 | |
| // the functions in this file are only intended to be used by
 | |
| // the bleve_dump utility and the debug http handlers
 | |
| // if your application relies on them, you're doing something wrong
 | |
| // they may change or be removed at any time
 | |
| 
 | |
| func dumpPrefix(kvreader store.KVReader, rv chan interface{}, prefix []byte) {
 | |
| 	start := prefix
 | |
| 	if start == nil {
 | |
| 		start = []byte{0}
 | |
| 	}
 | |
| 	it := kvreader.PrefixIterator(start)
 | |
| 	defer func() {
 | |
| 		cerr := it.Close()
 | |
| 		if cerr != nil {
 | |
| 			rv <- cerr
 | |
| 		}
 | |
| 	}()
 | |
| 	key, val, valid := it.Current()
 | |
| 	for valid {
 | |
| 		ck := make([]byte, len(key))
 | |
| 		copy(ck, key)
 | |
| 		cv := make([]byte, len(val))
 | |
| 		copy(cv, val)
 | |
| 		row, err := ParseFromKeyValue(ck, cv)
 | |
| 		if err != nil {
 | |
| 			rv <- err
 | |
| 			return
 | |
| 		}
 | |
| 		rv <- row
 | |
| 
 | |
| 		it.Next()
 | |
| 		key, val, valid = it.Current()
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func dumpRange(kvreader store.KVReader, rv chan interface{}, start, end []byte) {
 | |
| 	it := kvreader.RangeIterator(start, end)
 | |
| 	defer func() {
 | |
| 		cerr := it.Close()
 | |
| 		if cerr != nil {
 | |
| 			rv <- cerr
 | |
| 		}
 | |
| 	}()
 | |
| 	key, val, valid := it.Current()
 | |
| 	for valid {
 | |
| 		ck := make([]byte, len(key))
 | |
| 		copy(ck, key)
 | |
| 		cv := make([]byte, len(val))
 | |
| 		copy(cv, val)
 | |
| 		row, err := ParseFromKeyValue(ck, cv)
 | |
| 		if err != nil {
 | |
| 			rv <- err
 | |
| 			return
 | |
| 		}
 | |
| 		rv <- row
 | |
| 
 | |
| 		it.Next()
 | |
| 		key, val, valid = it.Current()
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func (i *IndexReader) DumpAll() chan interface{} {
 | |
| 	rv := make(chan interface{})
 | |
| 	go func() {
 | |
| 		defer close(rv)
 | |
| 		dumpRange(i.kvreader, rv, nil, nil)
 | |
| 	}()
 | |
| 	return rv
 | |
| }
 | |
| 
 | |
| func (i *IndexReader) DumpFields() chan interface{} {
 | |
| 	rv := make(chan interface{})
 | |
| 	go func() {
 | |
| 		defer close(rv)
 | |
| 		dumpPrefix(i.kvreader, rv, []byte{'f'})
 | |
| 	}()
 | |
| 	return rv
 | |
| }
 | |
| 
 | |
| type keyset [][]byte
 | |
| 
 | |
| func (k keyset) Len() int           { return len(k) }
 | |
| func (k keyset) Swap(i, j int)      { k[i], k[j] = k[j], k[i] }
 | |
| func (k keyset) Less(i, j int) bool { return bytes.Compare(k[i], k[j]) < 0 }
 | |
| 
 | |
| // DumpDoc returns all rows in the index related to this doc id
 | |
| func (i *IndexReader) DumpDoc(id string) chan interface{} {
 | |
| 	idBytes := []byte(id)
 | |
| 
 | |
| 	rv := make(chan interface{})
 | |
| 
 | |
| 	go func() {
 | |
| 		defer close(rv)
 | |
| 
 | |
| 		back, err := backIndexRowForDoc(i.kvreader, []byte(id))
 | |
| 		if err != nil {
 | |
| 			rv <- err
 | |
| 			return
 | |
| 		}
 | |
| 
 | |
| 		// no such doc
 | |
| 		if back == nil {
 | |
| 			return
 | |
| 		}
 | |
| 		// build sorted list of term keys
 | |
| 		keys := make(keyset, 0)
 | |
| 		for _, entry := range back.termsEntries {
 | |
| 			for i := range entry.Terms {
 | |
| 				tfr := NewTermFrequencyRow([]byte(entry.Terms[i]), uint16(*entry.Field), idBytes, 0, 0)
 | |
| 				key := tfr.Key()
 | |
| 				keys = append(keys, key)
 | |
| 			}
 | |
| 		}
 | |
| 		sort.Sort(keys)
 | |
| 
 | |
| 		// first add all the stored rows
 | |
| 		storedRowPrefix := NewStoredRow(idBytes, 0, []uint64{}, 'x', []byte{}).ScanPrefixForDoc()
 | |
| 		dumpPrefix(i.kvreader, rv, storedRowPrefix)
 | |
| 
 | |
| 		// now walk term keys in order and add them as well
 | |
| 		if len(keys) > 0 {
 | |
| 			it := i.kvreader.RangeIterator(keys[0], nil)
 | |
| 			defer func() {
 | |
| 				cerr := it.Close()
 | |
| 				if cerr != nil {
 | |
| 					rv <- cerr
 | |
| 				}
 | |
| 			}()
 | |
| 
 | |
| 			for _, key := range keys {
 | |
| 				it.Seek(key)
 | |
| 				rkey, rval, valid := it.Current()
 | |
| 				if !valid {
 | |
| 					break
 | |
| 				}
 | |
| 				rck := make([]byte, len(rkey))
 | |
| 				copy(rck, key)
 | |
| 				rcv := make([]byte, len(rval))
 | |
| 				copy(rcv, rval)
 | |
| 				row, err := ParseFromKeyValue(rck, rcv)
 | |
| 				if err != nil {
 | |
| 					rv <- err
 | |
| 					return
 | |
| 				}
 | |
| 				rv <- row
 | |
| 			}
 | |
| 		}
 | |
| 	}()
 | |
| 
 | |
| 	return rv
 | |
| }
 |