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.

113 lines
2.7 KiB

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