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.

73 lines
2.0 KiB

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