add redis3
This commit is contained in:
@@ -35,7 +35,7 @@ func (nb *NameBatch) DeleteName(name string) {
|
||||
}
|
||||
func (nb *NameBatch) ListNames(startFrom string, visitNamesFn func(name string) bool) bool {
|
||||
var names []string
|
||||
needFilter := startFrom == ""
|
||||
needFilter := startFrom != ""
|
||||
for n := range nb.names {
|
||||
if !needFilter || strings.Compare(n, startFrom) >= 0 {
|
||||
names = append(names, n)
|
||||
|
||||
@@ -9,7 +9,7 @@ type NameList struct {
|
||||
batchSize int
|
||||
}
|
||||
|
||||
func NewNameList(store ListStore, batchSize int) *NameList {
|
||||
func newNameList(store ListStore, batchSize int) *NameList {
|
||||
return &NameList{
|
||||
skipList: New(store),
|
||||
batchSize: batchSize,
|
||||
@@ -59,6 +59,7 @@ There are multiple cases after finding the name for greater or equal node
|
||||
|
||||
*/
|
||||
func (nl *NameList) WriteName(name string) error {
|
||||
|
||||
lookupKey := []byte(name)
|
||||
prevNode, nextNode, found, err := nl.skipList.FindGreaterOrEqual(lookupKey)
|
||||
if err != nil {
|
||||
@@ -301,3 +302,25 @@ func (nl *NameList) ListNames(startFrom string, visitNamesFn func(name string) b
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (nl *NameList) RemoteAllListElement() error {
|
||||
|
||||
t := nl.skipList
|
||||
|
||||
nodeRef := t.startLevels[0]
|
||||
for nodeRef != nil {
|
||||
node, err := t.loadElement(nodeRef)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if node == nil {
|
||||
return nil
|
||||
}
|
||||
if err := t.deleteElement(node); err != nil {
|
||||
return err
|
||||
}
|
||||
nodeRef = node.Next[0]
|
||||
}
|
||||
return nil
|
||||
|
||||
}
|
||||
71
weed/util/skiplist/name_list_serde.go
Normal file
71
weed/util/skiplist/name_list_serde.go
Normal file
@@ -0,0 +1,71 @@
|
||||
package skiplist
|
||||
|
||||
import (
|
||||
"github.com/chrislusf/seaweedfs/weed/glog"
|
||||
"github.com/golang/protobuf/proto"
|
||||
)
|
||||
|
||||
func LoadNameList(data []byte, store ListStore, batchSize int) *NameList {
|
||||
|
||||
nl := &NameList{
|
||||
skipList: New(store),
|
||||
batchSize: batchSize,
|
||||
}
|
||||
|
||||
if len(data) == 0 {
|
||||
return nl
|
||||
}
|
||||
|
||||
message := &SkipListProto{}
|
||||
if err := proto.Unmarshal(data, message); err != nil {
|
||||
glog.Errorf("loading skiplist: %v", err)
|
||||
}
|
||||
nl.skipList.maxNewLevel = int(message.MaxNewLevel)
|
||||
nl.skipList.maxLevel = int(message.MaxLevel)
|
||||
for i, ref := range message.StartLevels {
|
||||
nl.skipList.startLevels[i] = &SkipListElementReference{
|
||||
ElementPointer: ref.ElementPointer,
|
||||
Key: ref.Key,
|
||||
}
|
||||
}
|
||||
for i, ref := range message.EndLevels {
|
||||
nl.skipList.endLevels[i] = &SkipListElementReference{
|
||||
ElementPointer: ref.ElementPointer,
|
||||
Key: ref.Key,
|
||||
}
|
||||
}
|
||||
return nl
|
||||
}
|
||||
|
||||
func (nl *NameList) HasChanges() bool {
|
||||
return nl.skipList.hasChanges
|
||||
}
|
||||
|
||||
func (nl *NameList) ToBytes() []byte {
|
||||
message := &SkipListProto{}
|
||||
message.MaxNewLevel = int32(nl.skipList.maxNewLevel)
|
||||
message.MaxLevel = int32(nl.skipList.maxLevel)
|
||||
for _, ref := range nl.skipList.startLevels {
|
||||
if ref == nil {
|
||||
break
|
||||
}
|
||||
message.StartLevels = append(message.StartLevels, &SkipListElementReference{
|
||||
ElementPointer: ref.ElementPointer,
|
||||
Key: ref.Key,
|
||||
})
|
||||
}
|
||||
for _, ref := range nl.skipList.endLevels {
|
||||
if ref == nil {
|
||||
break
|
||||
}
|
||||
message.EndLevels = append(message.EndLevels, &SkipListElementReference{
|
||||
ElementPointer: ref.ElementPointer,
|
||||
Key: ref.Key,
|
||||
})
|
||||
}
|
||||
data, err := proto.Marshal(message)
|
||||
if err != nil {
|
||||
glog.Errorf("marshal skiplist: %v", err)
|
||||
}
|
||||
return data
|
||||
}
|
||||
@@ -15,7 +15,7 @@ func String(x int) string {
|
||||
}
|
||||
|
||||
func TestNameList(t *testing.T) {
|
||||
list := NewNameList(memStore, 7)
|
||||
list := newNameList(memStore, 7)
|
||||
|
||||
for i := 0; i < maxNameCount; i++ {
|
||||
list.WriteName(String(i))
|
||||
@@ -51,7 +51,7 @@ func TestNameList(t *testing.T) {
|
||||
}
|
||||
|
||||
// randomized deletion
|
||||
list = NewNameList(memStore, 7)
|
||||
list = newNameList(memStore, 7)
|
||||
// Delete elements at random positions in the list.
|
||||
rList := rand.Perm(maxN)
|
||||
for _, i := range rList {
|
||||
|
||||
@@ -22,6 +22,7 @@ type SkipList struct {
|
||||
maxNewLevel int
|
||||
maxLevel int
|
||||
listStore ListStore
|
||||
hasChanges bool
|
||||
// elementCount int
|
||||
}
|
||||
|
||||
@@ -93,6 +94,9 @@ func (t *SkipList) findExtended(key []byte, findGreaterOrEqual bool) (prevElemen
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if currentNode == nil {
|
||||
return
|
||||
}
|
||||
|
||||
// In case, that our first element is already greater-or-equal!
|
||||
if findGreaterOrEqual && compareElement(currentNode, key) > 0 {
|
||||
@@ -115,6 +119,9 @@ func (t *SkipList) findExtended(key []byte, findGreaterOrEqual bool) (prevElemen
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if currentNode == nil {
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if index > 0 {
|
||||
|
||||
@@ -126,6 +133,9 @@ func (t *SkipList) findExtended(key []byte, findGreaterOrEqual bool) (prevElemen
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if currentNodeNext == nil {
|
||||
return
|
||||
}
|
||||
foundElem = currentNodeNext
|
||||
ok = true
|
||||
return
|
||||
@@ -216,9 +226,11 @@ func (t *SkipList) Delete(key []byte) (err error) {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
nextNextNode.Prev = currentNode.Reference()
|
||||
if err = t.saveElement(nextNextNode); err != nil {
|
||||
return err
|
||||
if nextNextNode != nil {
|
||||
nextNextNode.Prev = currentNode.Reference()
|
||||
if err = t.saveElement(nextNextNode); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
// t.elementCount--
|
||||
@@ -230,6 +242,7 @@ func (t *SkipList) Delete(key []byte) (err error) {
|
||||
// Link from start needs readjustments.
|
||||
startNextKey := t.startLevels[index].Key
|
||||
if compareElement(nextNode, startNextKey) == 0 {
|
||||
t.hasChanges = true
|
||||
t.startLevels[index] = nextNode.Next[index]
|
||||
// This was our currently highest node!
|
||||
if t.startLevels[index] == nil {
|
||||
@@ -240,6 +253,7 @@ func (t *SkipList) Delete(key []byte) (err error) {
|
||||
// Link from end needs readjustments.
|
||||
if nextNode.Next[index] == nil {
|
||||
t.endLevels[index] = currentNode.Reference()
|
||||
t.hasChanges = true
|
||||
}
|
||||
nextNode.Next[index] = nil
|
||||
}
|
||||
@@ -260,7 +274,7 @@ func (t *SkipList) Delete(key []byte) (err error) {
|
||||
|
||||
// Insert inserts the given ListElement into the skiplist.
|
||||
// Insert runs in approx. O(log(n))
|
||||
func (t *SkipList) Insert(key, value []byte) (err error){
|
||||
func (t *SkipList) Insert(key, value []byte) (err error) {
|
||||
|
||||
if t == nil || key == nil {
|
||||
return
|
||||
@@ -272,6 +286,7 @@ func (t *SkipList) Insert(key, value []byte) (err error){
|
||||
if level > t.maxLevel {
|
||||
level = t.maxLevel + 1
|
||||
t.maxLevel = level
|
||||
t.hasChanges = true
|
||||
}
|
||||
|
||||
elem := &SkipListElement{
|
||||
@@ -326,9 +341,11 @@ func (t *SkipList) Insert(key, value []byte) (err error){
|
||||
if nextNode, err = t.loadElement(nextNodeRef); err != nil {
|
||||
return
|
||||
}
|
||||
nextNode.Prev = elem.Reference()
|
||||
if err = t.saveElement(nextNode); err != nil {
|
||||
return
|
||||
if nextNode != nil {
|
||||
nextNode.Prev = elem.Reference()
|
||||
if err = t.saveElement(nextNode); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -343,6 +360,9 @@ func (t *SkipList) Insert(key, value []byte) (err error){
|
||||
}
|
||||
}
|
||||
currentNode = nextNode
|
||||
if currentNode == nil {
|
||||
return
|
||||
}
|
||||
} else {
|
||||
// Go down
|
||||
index--
|
||||
@@ -366,18 +386,22 @@ func (t *SkipList) Insert(key, value []byte) (err error){
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
startLevelElement.Prev = elem.Reference()
|
||||
if err = t.saveElement(startLevelElement); err != nil {
|
||||
return err
|
||||
if startLevelElement != nil {
|
||||
startLevelElement.Prev = elem.Reference()
|
||||
if err = t.saveElement(startLevelElement); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
elem.Next[i] = t.startLevels[i]
|
||||
t.startLevels[i] = elem.Reference()
|
||||
t.hasChanges = true
|
||||
}
|
||||
|
||||
// link the endLevels to this element!
|
||||
if elem.Next[i] == nil {
|
||||
t.endLevels[i] = elem.Reference()
|
||||
t.hasChanges = true
|
||||
}
|
||||
|
||||
didSomething = true
|
||||
@@ -392,20 +416,24 @@ func (t *SkipList) Insert(key, value []byte) (err error){
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
endLevelElement.Next[i] = elem.Reference()
|
||||
if err = t.saveElement(endLevelElement); err != nil {
|
||||
return err
|
||||
if endLevelElement != nil {
|
||||
endLevelElement.Next[i] = elem.Reference()
|
||||
if err = t.saveElement(endLevelElement); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
if i == 0 {
|
||||
elem.Prev = t.endLevels[i]
|
||||
}
|
||||
t.endLevels[i] = elem.Reference()
|
||||
t.hasChanges = true
|
||||
}
|
||||
|
||||
// Link the startLevels to this element!
|
||||
if t.startLevels[i] == nil || bytes.Compare(t.startLevels[i].Key, key) > 0 {
|
||||
t.startLevels[i] = elem.Reference()
|
||||
t.hasChanges = true
|
||||
}
|
||||
|
||||
didSomething = true
|
||||
@@ -486,6 +514,9 @@ func (t *SkipList) println() {
|
||||
for nodeRef != nil {
|
||||
print(fmt.Sprintf("%v: ", string(nodeRef.Key)))
|
||||
node, _ := t.loadElement(nodeRef)
|
||||
if node == nil {
|
||||
break
|
||||
}
|
||||
for i := 0; i <= int(node.Level); i++ {
|
||||
|
||||
l := node.Next[i]
|
||||
@@ -510,8 +541,8 @@ func (t *SkipList) println() {
|
||||
}
|
||||
|
||||
}
|
||||
println()
|
||||
nodeRef = node.Next[0]
|
||||
println()
|
||||
}
|
||||
|
||||
print("end --> ")
|
||||
|
||||
Reference in New Issue
Block a user