database/bitcask/bitcask_search.go

84 lines
2.0 KiB
Go
Raw Normal View History

2022-01-09 00:59:10 +00:00
package bitcask
2022-01-01 22:22:08 +00:00
import (
"strings"
2022-07-26 04:36:46 +00:00
"git.tcp.direct/tcp.direct/database/kv"
2022-01-01 22:22:08 +00:00
)
2022-01-09 03:01:15 +00:00
// Search will search for a given string within all values inside of a Store.
// Note, type casting will be necessary. (e.g: []byte or string)
2022-07-26 04:36:46 +00:00
func (s Store) Search(query string) (<-chan *kv.KeyValue, chan error) {
var errChan = make(chan error)
var resChan = make(chan *kv.KeyValue, 5)
go func() {
defer func() {
close(resChan)
close(errChan)
}()
2022-08-29 06:36:37 +00:00
for _, key := range s.Keys() {
2022-07-26 04:36:46 +00:00
raw, err := s.Get(key)
if err != nil {
errChan <- err
continue
}
if raw != nil && strings.Contains(string(raw), query) {
keyVal := kv.NewKeyValue(kv.NewKey(key), kv.NewValue(raw))
resChan <- keyVal
}
2022-01-01 22:22:08 +00:00
}
2022-07-26 04:36:46 +00:00
}()
return resChan, errChan
2022-01-01 22:22:08 +00:00
}
2022-08-29 06:36:37 +00:00
// ValueExists will check for the existence of a Value anywhere within the keyspace;
// returning the first Key found, true if found || nil and false if not found.
2022-07-26 04:36:46 +00:00
func (s Store) ValueExists(value []byte) (key []byte, ok bool) {
2022-01-01 22:22:08 +00:00
var raw []byte
2022-07-26 04:36:46 +00:00
var needle = kv.NewValue(value)
2022-08-29 06:36:37 +00:00
for _, key = range s.Keys() {
raw, _ = s.Get(key)
2022-07-26 04:36:46 +00:00
v := kv.NewValue(raw)
2022-01-09 03:32:42 +00:00
if v.Equal(needle) {
2022-01-01 22:22:08 +00:00
ok = true
return
}
}
return
}
2022-01-09 03:01:15 +00:00
// PrefixScan will scan a Store for all keys that have a matching prefix of the given string
// and return a map of keys and values. (map[Key]Value)
2022-07-26 04:36:46 +00:00
func (s Store) PrefixScan(prefix string) (<-chan *kv.KeyValue, chan error) {
errChan := make(chan error)
resChan := make(chan *kv.KeyValue, 5)
go func() {
var err error
defer func(e error) {
if e != nil {
errChan <- e
}
close(resChan)
close(errChan)
}(err)
err = s.Scan([]byte(prefix), func(key []byte) error {
2022-08-29 10:30:39 +00:00
raw, _ := s.Get(key)
2022-07-26 04:36:46 +00:00
if key != nil && raw != nil {
k := kv.NewKey(key)
resChan <- kv.NewKeyValue(k, kv.NewValue(raw))
}
return nil
})
}()
return resChan, errChan
2022-01-01 22:22:08 +00:00
}
2022-08-29 06:36:37 +00:00
// Keys will return all keys in the database as a slice of byte slices.
func (s Store) Keys() (keys [][]byte) {
allkeys := s.Bitcask.Keys()
for key := range allkeys {
2022-01-09 03:01:15 +00:00
keys = append(keys, key)
2022-01-01 22:22:08 +00:00
}
return
}