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.

87 lines
2.4 KiB

  1. package embedded_filer
  2. import (
  3. "bytes"
  4. "github.com/chrislusf/seaweedfs/weed/filer"
  5. "github.com/chrislusf/seaweedfs/weed/glog"
  6. "github.com/syndtr/goleveldb/leveldb"
  7. "github.com/syndtr/goleveldb/leveldb/util"
  8. )
  9. /*
  10. The entry in level db has this format:
  11. key: genKey(dirId, fileName)
  12. value: []byte(fid)
  13. And genKey(dirId, fileName) use first 4 bytes to store dirId, and rest for fileName
  14. */
  15. type FileListInLevelDb struct {
  16. db *leveldb.DB
  17. }
  18. func NewFileListInLevelDb(dir string) (fl *FileListInLevelDb, err error) {
  19. fl = &FileListInLevelDb{}
  20. if fl.db, err = leveldb.OpenFile(dir, nil); err != nil {
  21. return
  22. }
  23. return
  24. }
  25. func genKey(dirId filer.DirectoryId, fileName string) []byte {
  26. ret := make([]byte, 0, 4+len(fileName))
  27. for i := 3; i >= 0; i-- {
  28. ret = append(ret, byte(dirId>>(uint(i)*8)))
  29. }
  30. ret = append(ret, []byte(fileName)...)
  31. return ret
  32. }
  33. func (fl *FileListInLevelDb) CreateFile(dirId filer.DirectoryId, fileName string, fid string) (err error) {
  34. glog.V(4).Infoln("directory", dirId, "fileName", fileName, "fid", fid)
  35. return fl.db.Put(genKey(dirId, fileName), []byte(fid), nil)
  36. }
  37. func (fl *FileListInLevelDb) DeleteFile(dirId filer.DirectoryId, fileName string) (fid string, err error) {
  38. if fid, err = fl.FindFile(dirId, fileName); err != nil {
  39. if err == leveldb.ErrNotFound {
  40. return "", nil
  41. }
  42. return
  43. }
  44. err = fl.db.Delete(genKey(dirId, fileName), nil)
  45. return fid, err
  46. }
  47. func (fl *FileListInLevelDb) FindFile(dirId filer.DirectoryId, fileName string) (fid string, err error) {
  48. data, e := fl.db.Get(genKey(dirId, fileName), nil)
  49. if e == leveldb.ErrNotFound {
  50. return "", filer.ErrNotFound
  51. } else if e != nil {
  52. return "", e
  53. }
  54. return string(data), nil
  55. }
  56. func (fl *FileListInLevelDb) ListFiles(dirId filer.DirectoryId, lastFileName string, limit int) (files []filer.FileEntry) {
  57. glog.V(4).Infoln("directory", dirId, "lastFileName", lastFileName, "limit", limit)
  58. dirKey := genKey(dirId, "")
  59. iter := fl.db.NewIterator(&util.Range{Start: genKey(dirId, lastFileName)}, nil)
  60. limitCounter := 0
  61. for iter.Next() {
  62. key := iter.Key()
  63. if !bytes.HasPrefix(key, dirKey) {
  64. break
  65. }
  66. fileName := string(key[len(dirKey):])
  67. if fileName == lastFileName {
  68. continue
  69. }
  70. limitCounter++
  71. if limit > 0 {
  72. if limitCounter > limit {
  73. break
  74. }
  75. }
  76. files = append(files, filer.FileEntry{Name: fileName, Id: filer.FileId(string(iter.Value()))})
  77. }
  78. iter.Release()
  79. return
  80. }