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.

85 lines
2.3 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 != nil {
  50. return "", e
  51. }
  52. return string(data), nil
  53. }
  54. func (fl *FileListInLevelDb) ListFiles(dirId filer.DirectoryId, lastFileName string, limit int) (files []filer.FileEntry) {
  55. glog.V(4).Infoln("directory", dirId, "lastFileName", lastFileName, "limit", limit)
  56. dirKey := genKey(dirId, "")
  57. iter := fl.db.NewIterator(&util.Range{Start: genKey(dirId, lastFileName)}, nil)
  58. limitCounter := 0
  59. for iter.Next() {
  60. key := iter.Key()
  61. if !bytes.HasPrefix(key, dirKey) {
  62. break
  63. }
  64. fileName := string(key[len(dirKey):])
  65. if fileName == lastFileName {
  66. continue
  67. }
  68. limitCounter++
  69. if limit > 0 {
  70. if limitCounter > limit {
  71. break
  72. }
  73. }
  74. files = append(files, filer.FileEntry{Name: fileName, Id: filer.FileId(string(iter.Value()))})
  75. }
  76. iter.Release()
  77. return
  78. }