97 lines
2.1 KiB
Go
97 lines
2.1 KiB
Go
// Copyright (C) 2019 Storj Labs, Inc.
|
|
// See LICENSE for copying information.
|
|
|
|
package storage
|
|
|
|
import (
|
|
"bytes"
|
|
"sort"
|
|
)
|
|
|
|
// IteratorFunc implements basic iterator
|
|
type IteratorFunc func(item *ListItem) bool
|
|
|
|
// Next returns the next item
|
|
func (next IteratorFunc) Next(item *ListItem) bool { return next(item) }
|
|
|
|
// SelectPrefixed keeps only items that have prefix
|
|
// items will be reused and modified
|
|
// TODO: remove this
|
|
func SelectPrefixed(items Items, prefix []byte) Items {
|
|
result := items[:0]
|
|
for _, item := range items {
|
|
if bytes.HasPrefix(item.Key, prefix) {
|
|
result = append(result, item)
|
|
}
|
|
}
|
|
return result
|
|
}
|
|
|
|
// SortAndCollapse sorts items and combines elements based on Delimiter
|
|
// items will be reused and modified
|
|
// TODO: remove this
|
|
func SortAndCollapse(items Items, prefix []byte) Items {
|
|
sort.Sort(items)
|
|
result := items[:0]
|
|
|
|
var currentPrefix []byte
|
|
var prefixed bool
|
|
for _, item := range items {
|
|
if prefixed {
|
|
if bytes.HasPrefix(item.Key, currentPrefix) {
|
|
continue
|
|
}
|
|
prefixed = false
|
|
}
|
|
|
|
if p := bytes.IndexByte(item.Key[len(prefix):], Delimiter); p >= 0 {
|
|
currentPrefix = item.Key[:len(prefix)+p+1]
|
|
prefixed = true
|
|
result = append(result, ListItem{
|
|
Key: currentPrefix,
|
|
IsPrefix: true,
|
|
})
|
|
} else {
|
|
result = append(result, item)
|
|
}
|
|
}
|
|
|
|
return result
|
|
}
|
|
|
|
// ReverseItems reverses items in the list
|
|
// items will be reused and modified
|
|
// TODO: remove this
|
|
func ReverseItems(items Items) Items {
|
|
for i := len(items)/2 - 1; i >= 0; i-- {
|
|
k := len(items) - 1 - i
|
|
items[i], items[k] = items[k], items[i]
|
|
}
|
|
return items
|
|
}
|
|
|
|
// ReverseKeys reverses the list of keys
|
|
func ReverseKeys(keys Keys) Keys {
|
|
for i := len(keys)/2 - 1; i >= 0; i-- {
|
|
k := len(keys) - 1 - i
|
|
keys[i], keys[k] = keys[k], keys[i]
|
|
}
|
|
return keys
|
|
}
|
|
|
|
// StaticIterator implements an iterator over list of items
|
|
type StaticIterator struct {
|
|
Items Items
|
|
Index int
|
|
}
|
|
|
|
// Next returns the next item from the iterator
|
|
func (it *StaticIterator) Next(item *ListItem) bool {
|
|
if it.Index >= len(it.Items) {
|
|
return false
|
|
}
|
|
*item = it.Items[it.Index]
|
|
it.Index++
|
|
return true
|
|
}
|