You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

114 lines
2.9 KiB

7 years ago
6 years ago
7 years ago
  1. package memdb
  2. import (
  3. "context"
  4. "fmt"
  5. "github.com/chrislusf/seaweedfs/weed/filer2"
  6. "github.com/chrislusf/seaweedfs/weed/util"
  7. "github.com/google/btree"
  8. "strings"
  9. )
  10. func init() {
  11. filer2.Stores = append(filer2.Stores, &MemDbStore{})
  12. }
  13. type MemDbStore struct {
  14. tree *btree.BTree
  15. }
  16. type entryItem struct {
  17. *filer2.Entry
  18. }
  19. func (a entryItem) Less(b btree.Item) bool {
  20. return strings.Compare(string(a.FullPath), string(b.(entryItem).FullPath)) < 0
  21. }
  22. func (store *MemDbStore) GetName() string {
  23. return "memory"
  24. }
  25. func (store *MemDbStore) Initialize(configuration util.Configuration) (err error) {
  26. store.tree = btree.New(8)
  27. return nil
  28. }
  29. func (store *MemDbStore) InsertEntry(ctx context.Context, entry *filer2.Entry) (err error) {
  30. // println("inserting", entry.FullPath)
  31. store.tree.ReplaceOrInsert(entryItem{entry})
  32. return nil
  33. }
  34. func (store *MemDbStore) UpdateEntry(ctx context.Context, entry *filer2.Entry) (err error) {
  35. if _, err = store.FindEntry(ctx, entry.FullPath); err != nil {
  36. return fmt.Errorf("no such file %s : %v", entry.FullPath, err)
  37. }
  38. store.tree.ReplaceOrInsert(entryItem{entry})
  39. return nil
  40. }
  41. func (store *MemDbStore) FindEntry(ctx context.Context, fullpath filer2.FullPath) (entry *filer2.Entry, err error) {
  42. item := store.tree.Get(entryItem{&filer2.Entry{FullPath: fullpath}})
  43. if item == nil {
  44. return nil, filer2.ErrNotFound
  45. }
  46. entry = item.(entryItem).Entry
  47. return entry, nil
  48. }
  49. func (store *MemDbStore) DeleteEntry(ctx context.Context, fullpath filer2.FullPath) (err error) {
  50. store.tree.Delete(entryItem{&filer2.Entry{FullPath: fullpath}})
  51. return nil
  52. }
  53. func (store *MemDbStore) ListDirectoryEntries(ctx context.Context, fullpath filer2.FullPath, startFileName string, inclusive bool, limit int) (entries []*filer2.Entry, err error) {
  54. startFrom := string(fullpath)
  55. if startFileName != "" {
  56. startFrom = startFrom + "/" + startFileName
  57. }
  58. store.tree.AscendGreaterOrEqual(entryItem{&filer2.Entry{FullPath: filer2.FullPath(startFrom)}},
  59. func(item btree.Item) bool {
  60. if limit <= 0 {
  61. return false
  62. }
  63. entry := item.(entryItem).Entry
  64. // println("checking", entry.FullPath)
  65. if entry.FullPath == fullpath {
  66. // skipping the current directory
  67. // println("skipping the folder", entry.FullPath)
  68. return true
  69. }
  70. dir, name := entry.FullPath.DirAndName()
  71. if name == startFileName {
  72. if inclusive {
  73. limit--
  74. entries = append(entries, entry)
  75. }
  76. return true
  77. }
  78. // only iterate the same prefix
  79. if !strings.HasPrefix(string(entry.FullPath), string(fullpath)) {
  80. // println("breaking from", entry.FullPath)
  81. return false
  82. }
  83. if dir != string(fullpath) {
  84. // this could be items in deeper directories
  85. // println("skipping deeper folder", entry.FullPath)
  86. return true
  87. }
  88. // now process the directory items
  89. // println("adding entry", entry.FullPath)
  90. limit--
  91. entries = append(entries, entry)
  92. return true
  93. },
  94. )
  95. return entries, nil
  96. }