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.

82 lines
2.2 KiB

  1. package embedded_filer
  2. import (
  3. "bytes"
  4. "github.com/chrislusf/weed-fs/go/filer"
  5. "github.com/chrislusf/weed-fs/go/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. return
  40. }
  41. err = fl.db.Delete(genKey(dirId, fileName), nil)
  42. return fid, err
  43. }
  44. func (fl *FileListInLevelDb) FindFile(dirId filer.DirectoryId, fileName string) (fid string, err error) {
  45. data, e := fl.db.Get(genKey(dirId, fileName), nil)
  46. if e != nil {
  47. return "", e
  48. }
  49. return string(data), nil
  50. }
  51. func (fl *FileListInLevelDb) ListFiles(dirId filer.DirectoryId, lastFileName string, limit int) (files []filer.FileEntry) {
  52. glog.V(4).Infoln("directory", dirId, "lastFileName", lastFileName, "limit", limit)
  53. dirKey := genKey(dirId, "")
  54. iter := fl.db.NewIterator(&util.Range{Start: genKey(dirId, lastFileName)}, nil)
  55. limitCounter := 0
  56. for iter.Next() {
  57. key := iter.Key()
  58. if !bytes.HasPrefix(key, dirKey) {
  59. break
  60. }
  61. fileName := string(key[len(dirKey):])
  62. if fileName == lastFileName {
  63. continue
  64. }
  65. limitCounter++
  66. if limit > 0 {
  67. if limitCounter > limit {
  68. break
  69. }
  70. }
  71. files = append(files, filer.FileEntry{Name: fileName, Id: filer.FileId(string(iter.Value()))})
  72. }
  73. iter.Release()
  74. return
  75. }