aboutsummaryrefslogtreecommitdiff
path: root/weed/filer/embedded_filer/files_in_leveldb.go
diff options
context:
space:
mode:
Diffstat (limited to 'weed/filer/embedded_filer/files_in_leveldb.go')
-rw-r--r--weed/filer/embedded_filer/files_in_leveldb.go85
1 files changed, 85 insertions, 0 deletions
diff --git a/weed/filer/embedded_filer/files_in_leveldb.go b/weed/filer/embedded_filer/files_in_leveldb.go
new file mode 100644
index 000000000..19f6dd7e8
--- /dev/null
+++ b/weed/filer/embedded_filer/files_in_leveldb.go
@@ -0,0 +1,85 @@
+package embedded_filer
+
+import (
+ "bytes"
+
+ "github.com/chrislusf/seaweedfs/weed/filer"
+ "github.com/chrislusf/seaweedfs/weed/glog"
+ "github.com/syndtr/goleveldb/leveldb"
+ "github.com/syndtr/goleveldb/leveldb/util"
+)
+
+/*
+The entry in level db has this format:
+ key: genKey(dirId, fileName)
+ value: []byte(fid)
+And genKey(dirId, fileName) use first 4 bytes to store dirId, and rest for fileName
+*/
+
+type FileListInLevelDb struct {
+ db *leveldb.DB
+}
+
+func NewFileListInLevelDb(dir string) (fl *FileListInLevelDb, err error) {
+ fl = &FileListInLevelDb{}
+ if fl.db, err = leveldb.OpenFile(dir, nil); err != nil {
+ return
+ }
+ return
+}
+
+func genKey(dirId filer.DirectoryId, fileName string) []byte {
+ ret := make([]byte, 0, 4+len(fileName))
+ for i := 3; i >= 0; i-- {
+ ret = append(ret, byte(dirId>>(uint(i)*8)))
+ }
+ ret = append(ret, []byte(fileName)...)
+ return ret
+}
+
+func (fl *FileListInLevelDb) CreateFile(dirId filer.DirectoryId, fileName string, fid string) (err error) {
+ glog.V(4).Infoln("directory", dirId, "fileName", fileName, "fid", fid)
+ return fl.db.Put(genKey(dirId, fileName), []byte(fid), nil)
+}
+func (fl *FileListInLevelDb) DeleteFile(dirId filer.DirectoryId, fileName string) (fid string, err error) {
+ if fid, err = fl.FindFile(dirId, fileName); err != nil {
+ if err == leveldb.ErrNotFound {
+ return "", nil
+ }
+ return
+ }
+ err = fl.db.Delete(genKey(dirId, fileName), nil)
+ return fid, err
+}
+func (fl *FileListInLevelDb) FindFile(dirId filer.DirectoryId, fileName string) (fid string, err error) {
+ data, e := fl.db.Get(genKey(dirId, fileName), nil)
+ if e != nil {
+ return "", e
+ }
+ return string(data), nil
+}
+func (fl *FileListInLevelDb) ListFiles(dirId filer.DirectoryId, lastFileName string, limit int) (files []filer.FileEntry) {
+ glog.V(4).Infoln("directory", dirId, "lastFileName", lastFileName, "limit", limit)
+ dirKey := genKey(dirId, "")
+ iter := fl.db.NewIterator(&util.Range{Start: genKey(dirId, lastFileName)}, nil)
+ limitCounter := 0
+ for iter.Next() {
+ key := iter.Key()
+ if !bytes.HasPrefix(key, dirKey) {
+ break
+ }
+ fileName := string(key[len(dirKey):])
+ if fileName == lastFileName {
+ continue
+ }
+ limitCounter++
+ if limit > 0 {
+ if limitCounter > limit {
+ break
+ }
+ }
+ files = append(files, filer.FileEntry{Name: fileName, Id: filer.FileId(string(iter.Value()))})
+ }
+ iter.Release()
+ return
+}