Chris Lu
7 years ago
7 changed files with 364 additions and 102 deletions
-
21weed/filer2/embedded/embedded_store.go
-
150weed/filer2/filer.go
-
53weed/filer2/filer_structure.go
-
30weed/filer2/filer_test.go
-
94weed/filer2/memdb/memdb_store.go
-
96weed/filer2/memdb/memdb_store_test.go
-
22weed/filer2/permission.go
@ -1,30 +0,0 @@ |
|||||
package filer2 |
|
||||
|
|
||||
import ( |
|
||||
"testing" |
|
||||
"path/filepath" |
|
||||
"fmt" |
|
||||
) |
|
||||
|
|
||||
func TestRecursion(t *testing.T) { |
|
||||
fullPath := "/home/chris/some/file/abc.jpg" |
|
||||
expected := []string{ |
|
||||
"/", "home", |
|
||||
"/home", "chris", |
|
||||
"/home/chris", "some", |
|
||||
"/home/chris/some", "file", |
|
||||
} |
|
||||
|
|
||||
dir, _ := filepath.Split(fullPath) |
|
||||
|
|
||||
i := 0 |
|
||||
|
|
||||
recursivelyEnsureDirectory(dir, func(parent, name string) error { |
|
||||
if parent != expected[i] || name != expected[i+1] { |
|
||||
t.Errorf("recursive directory is wrong! parent=%s dirName=%s", parent, name) |
|
||||
} |
|
||||
fmt.Printf("processing folder %s \t parent=%s\n", name, parent) |
|
||||
i += 2 |
|
||||
return nil |
|
||||
}) |
|
||||
} |
|
@ -0,0 +1,94 @@ |
|||||
|
package memdb |
||||
|
|
||||
|
import ( |
||||
|
"github.com/chrislusf/seaweedfs/weed/filer2" |
||||
|
"github.com/google/btree" |
||||
|
"strings" |
||||
|
"fmt" |
||||
|
) |
||||
|
|
||||
|
type MemDbStore struct { |
||||
|
tree *btree.BTree |
||||
|
} |
||||
|
|
||||
|
type Entry struct { |
||||
|
*filer2.Entry |
||||
|
} |
||||
|
|
||||
|
func (a Entry) Less(b btree.Item) bool { |
||||
|
return strings.Compare(string(a.FullPath), string(b.(Entry).FullPath)) < 0 |
||||
|
} |
||||
|
|
||||
|
func NewMemDbStore() (filer *MemDbStore) { |
||||
|
filer = &MemDbStore{} |
||||
|
filer.tree = btree.New(8) |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
func (filer *MemDbStore) InsertEntry(entry *filer2.Entry) (err error) { |
||||
|
// println("inserting", entry.FullPath)
|
||||
|
filer.tree.ReplaceOrInsert(Entry{entry}) |
||||
|
return nil |
||||
|
} |
||||
|
|
||||
|
func (filer *MemDbStore) AddDirectoryLink(directory *filer2.Entry, delta int32) (err error) { |
||||
|
directory.Nlink = uint32(int32(directory.Nlink) + delta) |
||||
|
return nil |
||||
|
} |
||||
|
|
||||
|
func (filer *MemDbStore) AppendFileChunk(fullpath filer2.FullPath, fileChunk filer2.FileChunk) (err error) { |
||||
|
found, entry, err := filer.FindEntry(fullpath) |
||||
|
if !found { |
||||
|
return fmt.Errorf("No such file: %s", fullpath) |
||||
|
} |
||||
|
entry.Chunks = append(entry.Chunks, fileChunk) |
||||
|
return nil |
||||
|
} |
||||
|
|
||||
|
func (filer *MemDbStore) FindEntry(fullpath filer2.FullPath) (found bool, entry *filer2.Entry, err error) { |
||||
|
item := filer.tree.Get(Entry{&filer2.Entry{FullPath: fullpath}}) |
||||
|
if item == nil { |
||||
|
return false, nil, nil |
||||
|
} |
||||
|
entry = item.(Entry).Entry |
||||
|
return true, entry, nil |
||||
|
} |
||||
|
|
||||
|
func (filer *MemDbStore) DeleteEntry(fullpath filer2.FullPath) (entry *filer2.Entry, err error) { |
||||
|
item := filer.tree.Delete(Entry{&filer2.Entry{FullPath: fullpath}}) |
||||
|
if item == nil { |
||||
|
return nil, nil |
||||
|
} |
||||
|
entry = item.(Entry).Entry |
||||
|
return entry, nil |
||||
|
} |
||||
|
|
||||
|
func (filer *MemDbStore) ListDirectoryEntries(fullpath filer2.FullPath) (entries []*filer2.Entry, err error) { |
||||
|
filer.tree.AscendGreaterOrEqual(Entry{&filer2.Entry{FullPath: fullpath}}, |
||||
|
func(item btree.Item) bool { |
||||
|
entry := item.(Entry).Entry |
||||
|
// println("checking", entry.FullPath)
|
||||
|
if entry.FullPath == fullpath { |
||||
|
// skipping the current directory
|
||||
|
// println("skipping the folder", entry.FullPath)
|
||||
|
return true |
||||
|
} |
||||
|
dir, _ := entry.FullPath.DirAndName() |
||||
|
if !strings.HasPrefix(dir, string(fullpath)) { |
||||
|
// println("directory is:", dir, "fullpath:", fullpath)
|
||||
|
// println("breaking from", entry.FullPath)
|
||||
|
return false |
||||
|
} |
||||
|
if dir != string(fullpath) { |
||||
|
// this could be items in deeper directories
|
||||
|
// println("skipping deeper folder", entry.FullPath)
|
||||
|
return true |
||||
|
} |
||||
|
// now process the directory items
|
||||
|
// println("adding entry", entry.FullPath)
|
||||
|
entries = append(entries, entry) |
||||
|
return true |
||||
|
}, |
||||
|
) |
||||
|
return entries, nil |
||||
|
} |
@ -0,0 +1,96 @@ |
|||||
|
package memdb |
||||
|
|
||||
|
import ( |
||||
|
"testing" |
||||
|
"github.com/chrislusf/seaweedfs/weed/filer2" |
||||
|
) |
||||
|
|
||||
|
func TestCreateAndFind(t *testing.T) { |
||||
|
filer := filer2.NewFiler("") |
||||
|
filer.SetStore(NewMemDbStore()) |
||||
|
filer.DisableDirectoryCache() |
||||
|
|
||||
|
fullpath := filer2.FullPath("/home/chris/this/is/one/file1.jpg") |
||||
|
|
||||
|
entry1 := &filer2.Entry{ |
||||
|
FullPath: fullpath, |
||||
|
Attr: filer2.Attr{ |
||||
|
Mode: 0440, |
||||
|
Uid: 1234, |
||||
|
Gid: 5678, |
||||
|
}, |
||||
|
} |
||||
|
|
||||
|
if err := filer.CreateEntry(entry1); err != nil { |
||||
|
t.Errorf("create entry %v: %v", entry1.FullPath, err) |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
found, entry, err := filer.FindEntry(fullpath) |
||||
|
|
||||
|
if err != nil { |
||||
|
t.Errorf("find entry: %v", err) |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
if !found { |
||||
|
t.Errorf("Failed to find newly created file") |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
if entry.FullPath != entry1.FullPath { |
||||
|
t.Errorf("find wrong entry: %v", entry.FullPath) |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
func TestCreateFileAndList(t *testing.T) { |
||||
|
filer := filer2.NewFiler("") |
||||
|
filer.SetStore(NewMemDbStore()) |
||||
|
filer.DisableDirectoryCache() |
||||
|
|
||||
|
entry1 := &filer2.Entry{ |
||||
|
FullPath: filer2.FullPath("/home/chris/this/is/one/file1.jpg"), |
||||
|
Attr: filer2.Attr{ |
||||
|
Mode: 0440, |
||||
|
Uid: 1234, |
||||
|
Gid: 5678, |
||||
|
}, |
||||
|
} |
||||
|
|
||||
|
entry2 := &filer2.Entry{ |
||||
|
FullPath: filer2.FullPath("/home/chris/this/is/one/file2.jpg"), |
||||
|
Attr: filer2.Attr{ |
||||
|
Mode: 0440, |
||||
|
Uid: 1234, |
||||
|
Gid: 5678, |
||||
|
}, |
||||
|
} |
||||
|
|
||||
|
filer.CreateEntry(entry1) |
||||
|
filer.CreateEntry(entry2) |
||||
|
|
||||
|
entries, err := filer.ListDirectoryEntries(filer2.FullPath("/home/chris/this/is/one/")) |
||||
|
|
||||
|
if err != nil { |
||||
|
t.Errorf("list entries: %v", err) |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
if len(entries) != 2 { |
||||
|
t.Errorf("list entries count: %v", len(entries)) |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
if entries[0].FullPath != entry1.FullPath { |
||||
|
t.Errorf("find wrong entry 1: %v", entries[0].FullPath) |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
if entries[1].FullPath != entry2.FullPath { |
||||
|
t.Errorf("find wrong entry 2: %v", entries[1].FullPath) |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,22 @@ |
|||||
|
package filer2 |
||||
|
|
||||
|
func hasWritePermission(dir *Entry, entry *Entry) bool { |
||||
|
|
||||
|
if dir == nil { |
||||
|
return false |
||||
|
} |
||||
|
|
||||
|
if dir.Uid == entry.Uid && dir.Mode&0200 > 0 { |
||||
|
return true |
||||
|
} |
||||
|
|
||||
|
if dir.Gid == entry.Gid && dir.Mode&0020 > 0 { |
||||
|
return true |
||||
|
} |
||||
|
|
||||
|
if dir.Mode&0002 > 0 { |
||||
|
return true |
||||
|
} |
||||
|
|
||||
|
return false |
||||
|
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue