diff --git a/alg/bplus.go b/alg/bplus.go deleted file mode 100644 index 79e67db..0000000 --- a/alg/bplus.go +++ /dev/null @@ -1,355 +0,0 @@ -package alg - -import "strings" - -type IndexKey interface { - Compare(other IndexKey) int -} - -type SortOrder struct { - Field string - Desc bool -} - -type IndexEntry struct { - Key IndexKey - Value interface{} -} - -const BTreeMinDegree = 2 - -type BTreeNode struct { - Keys []IndexKey - Values []interface{} // 叶子节点存储数据 - Childs []*BTreeNode // 非叶子节点存储子节点 - IsLeaf bool - Next *BTreeNode // 叶子节点之间的链表指针 - Prev *BTreeNode -} - -type BTree struct { - Root *BTreeNode -} - -func NewBTreeNode(leaf bool) *BTreeNode { - return &BTreeNode{ - Keys: make([]IndexKey, 0), - Values: make([]interface{}, 0), - Childs: make([]*BTreeNode, 0), - IsLeaf: leaf, - } -} - -func NewBTree() *BTree { - return &BTree{ - Root: NewBTreeNode(true), - } -} - -func (bt *BTree) Insert(key IndexKey, value interface{}) { - root := bt.Root - // 如果根节点已满,需要分裂 - if len(root.Keys) == 2*BTreeMinDegree-1 { - newRoot := NewBTreeNode(false) - newRoot.Childs = append(newRoot.Childs, root) - splitChild(newRoot, 0) - bt.Root = newRoot - } - insertNonFull(bt.Root, key, value) -} - -// 分裂子节点 -func splitChild(parent *BTreeNode, index int) { - minDegree := BTreeMinDegree - fullNode := parent.Childs[index] - // 创建新节点 - newNode := NewBTreeNode(fullNode.IsLeaf) - // 中间键位置 - mid := minDegree - 1 - - // 拆分键和值 - newNode.Keys = fullNode.Keys[mid:] - fullNode.Keys = fullNode.Keys[:mid] - - if !fullNode.IsLeaf { - newNode.Childs = fullNode.Childs[mid:] - fullNode.Childs = fullNode.Childs[:mid] - } else { - // 叶子节点需要维护链表 - newNode.Values = fullNode.Values[mid:] - fullNode.Values = fullNode.Values[:mid] - newNode.Next = fullNode.Next - newNode.Prev = fullNode - if fullNode.Next != nil { - fullNode.Next.Prev = newNode - } - fullNode.Next = newNode - } - - // 将中间键提升到父节点 - parent.Keys = append(parent.Keys[:index+1], append([]IndexKey{fullNode.Keys[mid]}, parent.Keys[index+1:]...)...) - fullNode.Keys = fullNode.Keys[:mid] -} - -// 插入非满节点 -func insertNonFull(node *BTreeNode, key IndexKey, value interface{}) { - i := len(node.Keys) - 1 - - if node.IsLeaf { - // 在叶子节点插入 - for i >= 0 && key.Compare(node.Keys[i]) < 0 { - i-- - } - // 插入键值 - if i >= 0 { - node.Keys = append(node.Keys[:i+1], append([]IndexKey{key}, node.Keys[i+1:]...)...) - node.Values = append(node.Values[:i+1], append([]interface{}{value}, node.Values[i+1:]...)...) - } else { - node.Keys = append([]IndexKey{key}, node.Keys...) - node.Values = append([]interface{}{value}, node.Values...) - } - } else { - // 找到子节点 - for i >= 0 && key.Compare(node.Keys[i]) < 0 { - i-- - } - i++ - - // 如果子节点已满,需要分裂 - child := node.Childs[i] - if len(child.Keys) == 2*BTreeMinDegree-1 { - splitChild(node, i) - if key.Compare(node.Keys[i]) > 0 { - i++ // 选择正确的位置 - } - } - insertNonFull(node.Childs[i], key, value) - } -} - -func (bt *BTree) Search(key IndexKey) (interface{}, bool) { - node := bt.Root - for node != nil { - // 在当前节点查找位置 - i := 0 - for i < len(node.Keys) && key.Compare(node.Keys[i]) > 0 { - i++ - } - - if node.IsLeaf { - // 在叶子节点中查找精确匹配 - if i < len(node.Keys) && key.Compare(node.Keys[i]) == 0 { - return node.Values[i], true - } - return nil, false - } else { - // 继续查找子节点 - node = node.Childs[i] - } - } - return nil, false -} - -func (bt *BTree) Delete(key IndexKey) { - deleteFromNode(bt.Root, key) -} - -// 从节点删除指定键 -func deleteFromNode(node *BTreeNode, key IndexKey) { - minDegree := BTreeMinDegree - // 寻找键的位置 - i := 0 - for i < len(node.Keys) && key.Compare(node.Keys[i]) > 0 { - i++ - } - - if node.IsLeaf { - // 叶子节点直接删除 - if i < len(node.Keys) && key.Compare(node.Keys[i]) == 0 { - // 删除键值对 - node.Keys = append(node.Keys[:i], node.Keys[i+1:]...) - node.Values = append(node.Values[:i], node.Values[i+1:]...) - } - } else { - // 非叶子节点 - if i < len(node.Keys) && key.Compare(node.Keys[i]) == 0 { - // 找到键,需要替换为后继值 - child := node.Childs[i] - sibling := node.Childs[i+1] - - if len(child.Keys) >= minDegree { - // 前驱节点存在,替换为前驱 - predecessor := getPredecessor(child) - node.Keys[i] = predecessor - deleteFromNode(child, predecessor) - } else if len(sibling.Keys) >= minDegree { - // 后继节点存在,替换为后继 - successor := getSuccessor(sibling) - node.Keys[i] = successor - deleteFromNode(sibling, successor) - } else { - // 合并节点 - mergeNodes(node, i) - deleteFromNode(child, key) - } - } else { - // 继续删除子节点 - child := node.Childs[i] - if len(child.Keys) >= minDegree { - // 子节点足够大,继续删除 - deleteFromNode(child, key) - } else { - // 需要重新平衡 - if i > 0 && len(node.Childs[i-1].Keys) >= minDegree { - // 从左兄弟借 - borrowFromLeft(node, i) - } else if i < len(node.Childs)-1 && len(node.Childs[i+1].Keys) >= minDegree { - // 从右兄弟借 - borrowFromRight(node, i) - } else { - // 合并节点 - if i > 0 { - mergeNodes(node, i-1) - } else { - mergeNodes(node, i) - } - } - deleteFromNode(child, key) - } - } - } -} - -// 获取前驱节点 -func getPredecessor(node *BTreeNode) IndexKey { - for !node.IsLeaf { - node = node.Childs[len(node.Childs)-1] - } - return node.Keys[len(node.Keys)-1] -} - -// 获取后继节点 -func getSuccessor(node *BTreeNode) IndexKey { - for !node.IsLeaf { - node = node.Childs[0] - } - return node.Keys[0] -} - -// 合并节点 -func mergeNodes(parent *BTreeNode, index int) { - left := parent.Childs[index] - right := parent.Childs[index+1] - - // 将左节点和右节点合并 - left.Keys = append(left.Keys, parent.Keys[index]) - left.Keys = append(left.Keys, right.Keys...) - - if left.IsLeaf { - left.Values = append(left.Values, right.Values...) - left.Next = right.Next - if right.Next != nil { - right.Next.Prev = left - } - } else { - left.Childs = append(left.Childs, right.Childs...) - } - - // 更新父节点 - parent.Keys = append(parent.Keys[:index], parent.Keys[index+1:]...) - parent.Childs = append(parent.Childs[:index+1], parent.Childs[index+2:]...) -} - -// 从左兄弟借 -func borrowFromLeft(parent *BTreeNode, index int) { - left := parent.Childs[index-1] - current := parent.Childs[index] - - // 移动键 - current.Keys = append([]IndexKey{parent.Keys[index-1]}, current.Keys...) - if !left.IsLeaf { - current.Childs = append([]*BTreeNode{left.Childs[len(left.Childs)-1]}, current.Childs...) - left.Childs = left.Childs[:len(left.Childs)-1] - } - - // 更新父节点 - parent.Keys[index-1] = left.Keys[len(left.Keys)-1] - left.Keys = left.Keys[:len(left.Keys)-1] -} - -// 从右兄弟借 -func borrowFromRight(parent *BTreeNode, index int) { - current := parent.Childs[index] - right := parent.Childs[index+1] - - // 移动键 - current.Keys = append(current.Keys, parent.Keys[index]) - parent.Keys[index] = right.Keys[0] - - if !current.IsLeaf { - current.Childs = append(current.Childs, right.Childs[0]) - right.Childs = right.Childs[1:] - } - - right.Keys = right.Keys[1:] -} - -func (bt *BTree) Traverse(cb func(key IndexKey) bool) []interface{} { - result := make([]interface{}, 0) - // 找到最左边的叶子节点 - node := bt.Root - for node != nil && !node.IsLeaf { - node = node.Childs[0] - } - - // 遍历所有叶子节点 - for node != nil { - for i, key := range node.Keys { - if cb(key) { - result = append(result, node.Values[i]) - } else { - return result - } - } - node = node.Next - } - return result -} - -type MultiFieldKey struct { - Fields []string - SortDirs []bool // true 表示降序 - Values map[string]interface{} -} - -func (m MultiFieldKey) Compare(other IndexKey) int { - o := other.(MultiFieldKey) - for i, field := range m.Fields { - v1 := m.Values[field] - v2 := o.Values[field] - - var cmp int - switch v1.(type) { - case string: - cmp = strings.Compare(v1.(string), v2.(string)) - case float64: - if v1.(float64) < v2.(float64) { - cmp = -1 - } else if v1.(float64) > v2.(float64) { - cmp = 1 - } else { - cmp = 0 - } - default: - panic("Unsupported type") - } - - if cmp != 0 { - if m.SortDirs[i] { - return -cmp - } - return cmp - } - } - return 0 -} diff --git a/api/index.go b/api/index.go new file mode 100644 index 0000000..981796c --- /dev/null +++ b/api/index.go @@ -0,0 +1,8 @@ +package api + +import "git.pyer.club/kingecg/godocdb/index" + +type Index struct { + metadata index.IndexMetadata + store *index.IndexStore +} diff --git a/document/document.go b/document/document.go index bf63d97..dfae601 100644 --- a/document/document.go +++ b/document/document.go @@ -32,7 +32,7 @@ func NewDocumentStore(storeName string) (*DocumentStore, error) { storage.Close() return nil, fmt.Errorf("failed to create index store: %v", err) } - if errCreate := is.CreateIndex("default_index", index.NonUnique, []string{"_id"}, []index.IndexSortOrder{index.Ascending}); errCreate != nil { + if _, errCreate := is.CreateIndex("default_index", index.NonUnique, []string{"_id"}, []index.IndexSortOrder{index.Ascending}); errCreate != nil { return nil, errCreate } @@ -107,7 +107,7 @@ func (ds *DocumentStore) StoreDocument(collection string, id string, doc interfa // 创建默认索引(如果不存在) if _, err := ds.indexStore.GetIndexMetadata("default_index"); err != nil { // 如果索引不存在,创建默认索引 - if errCreate := ds.indexStore.CreateIndex("default_index", index.NonUnique, []string{"_id"}, nil); errCreate != nil { + if _, errCreate := ds.indexStore.CreateIndex("default_index", index.NonUnique, []string{"_id"}, nil); errCreate != nil { return errCreate } } diff --git a/index/index.go b/index/index.go index 60a0119..0172037 100644 --- a/index/index.go +++ b/index/index.go @@ -62,13 +62,13 @@ func NewIndexStore(storeName string) (*IndexStore, error) { } // CreateIndex 创建索引 -func (is *IndexStore) CreateIndex(indexName string, indexType IndexType, keyFields []string, sortOrders []IndexSortOrder) error { +func (is *IndexStore) CreateIndex(indexName string, indexType IndexType, keyFields []string, sortOrders []IndexSortOrder) (*IndexMetadata, error) { is.mu.Lock() defer is.mu.Unlock() // 验证keyFields和sortOrders长度一致 if len(keyFields) != len(sortOrders) { - return fmt.Errorf("keyFields and sortOrders must have the same length") + return nil, fmt.Errorf("keyFields and sortOrders must have the same length") } // 存储索引元数据 @@ -82,25 +82,26 @@ func (is *IndexStore) CreateIndex(indexName string, indexType IndexType, keyFiel data, err := bson.Marshal(metadata) if err != nil { - return fmt.Errorf("failed to marshal index metadata: %v", err) + return nil, fmt.Errorf("failed to marshal index metadata: %v", err) } key := []byte(fmt.Sprintf("indexes:metadata:%s", indexName)) if err := is.storage.Put(key, data); err != nil { - return err + return nil, err } + return &metadata, nil - // 初始化索引结构 - index := make(map[string]string) + // // 初始化索引结构 + // index := make(map[string]string) - // 存储初始索引结构 - indexKey := fmt.Sprintf("indexes:data:%s", indexName) - indexData, err := bson.Marshal(index) - if err != nil { - return fmt.Errorf("failed to marshal index data: %v", err) - } + // // 存储初始索引结构 + // indexKey := fmt.Sprintf("indexes:data:%s", indexName) + // indexData, err := bson.Marshal(index) + // if err != nil { + // return fmt.Errorf("failed to marshal index data: %v", err) + // } - return is.storage.Put([]byte(indexKey), indexData) + // return is.storage.Put([]byte(indexKey), indexData) } // UpdateIndex 在指定collection下更新索引 diff --git a/index/index_test.go b/index/index_test.go index c668311..b5e0483 100644 --- a/index/index_test.go +++ b/index/index_test.go @@ -24,7 +24,7 @@ func TestIndexStore(t *testing.T) { keyFields := []string{"name"} // 测试创建索引(默认升序) - if err := is.CreateIndex(indexName, NonUnique, keyFields, []IndexSortOrder{Ascending}); err != nil { + if _, err := is.CreateIndex(indexName, NonUnique, keyFields, []IndexSortOrder{Ascending}); err != nil { t.Errorf("CreateIndex failed: %v", err) } @@ -67,7 +67,7 @@ func TestCompositeIndex(t *testing.T) { keyFields := []string{"name", "age"} // 创建复合索引(默认升序) - if err := is.CreateIndex(indexName, NonUnique, keyFields, []IndexSortOrder{Ascending, Ascending}); err != nil { + if _, err := is.CreateIndex(indexName, NonUnique, keyFields, []IndexSortOrder{Ascending, Ascending}); err != nil { t.Errorf("CreateIndex failed: %v", err) } @@ -99,7 +99,7 @@ func TestIndexSortOrder(t *testing.T) { keyFields := []string{"timestamp"} // 测试创建升序索引 - if err := is.CreateIndex(indexName, NonUnique, keyFields, []IndexSortOrder{Ascending}); err != nil { + if _, err := is.CreateIndex(indexName, NonUnique, keyFields, []IndexSortOrder{Ascending}); err != nil { t.Errorf("CreateIndex failed: %v", err) } @@ -115,7 +115,7 @@ func TestIndexSortOrder(t *testing.T) { // 测试创建降序索引 indexNameDesc := "sorted_index_desc" - if err := is.CreateIndex(indexNameDesc, NonUnique, keyFields, []IndexSortOrder{Descending}); err != nil { + if _, err := is.CreateIndex(indexNameDesc, NonUnique, keyFields, []IndexSortOrder{Descending}); err != nil { t.Errorf("CreateIndex failed: %v", err) } @@ -147,7 +147,7 @@ func TestCompositeIndexSortOrders(t *testing.T) { sortOrders := []IndexSortOrder{Descending, Ascending} // 创建复合索引 - if err := is.CreateIndex(indexName, NonUnique, keyFields, sortOrders); err != nil { + if _, err := is.CreateIndex(indexName, NonUnique, keyFields, sortOrders); err != nil { t.Errorf("CreateIndex failed: %v", err) } @@ -206,7 +206,7 @@ func TestConcurrentIndexOperations(t *testing.T) { indexName := fmt.Sprintf("concurrent_index_%d", i) // 创建索引(默认升序) - if err := is.CreateIndex(indexName, NonUnique, []string{"name"}, []IndexSortOrder{Ascending}); err != nil { + if _, err := is.CreateIndex(indexName, NonUnique, []string{"name"}, []IndexSortOrder{Ascending}); err != nil { t.Errorf("CreateIndex failed: %v", err) }