This commit is contained in:
Jarek Kowalski committed 2016-04-01 19:26:06 -07:00
1 parent 778359e8c4
commit 417a34e584
9 files changed
+71 -69

No files matched your search

+2
View File
@@ -0,0 +1,2 @@
// Package cas implements Content-Addressable Storage
package cas
+35
View File
@@ -0,0 +1,35 @@
package fs
import (
"fmt"
"sort"
)
// Directory represents contents of a directory.
type Directory struct {
Entries []*Entry
}
// FindEntryName returns the pointer to an Entry with a given name or nil if not found.
func (d Directory) FindEntryName(name string) *Entry {
entries := d.Entries
i := sort.Search(
len(entries),
func(i int) bool { return entries[i].Name >= name },
)
if i < len(entries) && entries[i].Name == name {
return entries[i]
}
return nil
}
func (d Directory) String() string {
s := ""
for i, f := range d.Entries {
s += fmt.Sprintf("entry[%v] = %v\n", i, f)
}
return s
}
+2
View File
@@ -0,0 +1,2 @@
// Package fs implements filesystem layer on top content-addressable storage.
package fs
-6
View File
@@ -87,9 +87,3 @@ func (e *Entry) String() string {
e.Name, e.Type, e.ModTime, e.Size, e.ObjectID, e.UserID, e.GroupID,
)
}
// Directory contains access to contents of directory, both in original order and indexed by name.
type Directory struct {
Ordered []*Entry
ByName map[string]*Entry
}
+3 -34
View File
@@ -1,51 +1,20 @@
package fs
import (
"fmt"
"io/ioutil"
"os"
"sort"
)
// Listing encapsulates list of items in a directory.
type Listing struct {
Entries []*Entry
}
// FindEntryName returns the pointer to an Entry with a given name or nil if not found.
func (l Listing) FindEntryName(name string) *Entry {
entries := l.Entries
i := sort.Search(
len(entries),
func(i int) bool { return entries[i].Name >= name },
)
if i < len(entries) && entries[i].Name == name {
return entries[i]
}
return nil
}
func (l Listing) String() string {
s := ""
for i, f := range l.Entries {
s += fmt.Sprintf("entry[%v] = %v\n", i, f)
}
return s
}
// Lister lists contents of filesystem directories.
type Lister interface {
List(path string) (Listing, error)
List(path string) (Directory, error)
}
type filesystemLister struct {
}
func (l *filesystemLister) List(path string) (Listing, error) {
listing := Listing{}
func (d *filesystemLister) List(path string) (Directory, error) {
listing := Directory{}
entries, err := ioutil.ReadDir(path)
if err != nil {
return listing, err
+17 -17
View File
@@ -23,22 +23,22 @@ func TestLister(t *testing.T) {
lister := &filesystemLister{}
var listing Listing
var dir Directory
// Try listing directory that does not exist.
listing, err = lister.List(fmt.Sprintf("/no-such-dir-%v", time.Now().Nanosecond()))
dir, err = lister.List(fmt.Sprintf("/no-such-dir-%v", time.Now().Nanosecond()))
if err == nil {
t.Errorf("expected error when listing directory that does not exist.")
t.Errorf("expected error when dir directory that does not exist.")
}
// Now list an empty directory that does not exist.
listing, err = lister.List(tmp)
dir, err = lister.List(tmp)
if err != nil {
t.Errorf("error when listing empty directory: %v", err)
t.Errorf("error when dir empty directory: %v", err)
}
if len(listing.Entries) > 0 {
t.Errorf("expected empty directory, got %v", listing)
if len(dir.Entries) > 0 {
t.Errorf("expected empty directory, got %v", dir)
}
// Now list a directory with 3 files.
@@ -49,32 +49,32 @@ func TestLister(t *testing.T) {
os.Mkdir(filepath.Join(tmp, "z"), 0777)
os.Mkdir(filepath.Join(tmp, "y"), 0777)
listing, err = lister.List(tmp)
dir, err = lister.List(tmp)
if err != nil {
t.Errorf("error when listing directory with files: %v", err)
t.Errorf("error when dir directory with files: %v", err)
}
if len(listing.Entries) != 5 {
t.Errorf("expected 5 files, got: %v", listing)
if len(dir.Entries) != 5 {
t.Errorf("expected 5 files, got: %v", dir)
} else {
goodCount := 0
if listing.Entries[0].Name == "f1" && listing.Entries[0].Size == 5 && listing.Entries[0].Type == EntryTypeFile {
if dir.Entries[0].Name == "f1" && dir.Entries[0].Size == 5 && dir.Entries[0].Type == EntryTypeFile {
goodCount++
}
if listing.Entries[1].Name == "f2" && listing.Entries[1].Size == 4 && listing.Entries[1].Type == EntryTypeFile {
if dir.Entries[1].Name == "f2" && dir.Entries[1].Size == 4 && dir.Entries[1].Type == EntryTypeFile {
goodCount++
}
if listing.Entries[2].Name == "f3" && listing.Entries[2].Size == 3 && listing.Entries[2].Type == EntryTypeFile {
if dir.Entries[2].Name == "f3" && dir.Entries[2].Size == 3 && dir.Entries[2].Type == EntryTypeFile {
goodCount++
}
if listing.Entries[3].Name == "y" && listing.Entries[3].Size == 0 && listing.Entries[3].Type == EntryTypeDirectory {
if dir.Entries[3].Name == "y" && dir.Entries[3].Size == 0 && dir.Entries[3].Type == EntryTypeDirectory {
goodCount++
}
if listing.Entries[4].Name == "z" && listing.Entries[4].Size == 0 && listing.Entries[4].Type == EntryTypeDirectory {
if dir.Entries[4].Name == "z" && dir.Entries[4].Size == 0 && dir.Entries[4].Type == EntryTypeDirectory {
goodCount++
}
if goodCount != 5 {
t.Errorf("invalid listing data:\n%v", listing)
t.Errorf("invalid dir data:\n%v", dir)
}
}
}
+1 -1
View File
@@ -65,7 +65,7 @@ func (u *uploader) UploadDir(path string, previous cas.ObjectID) (cas.ObjectID,
return cas.NullObjectID, err
}
var cached Listing
var cached Directory
if previous != "" {
if r, err := u.mgr.Open(previous); err == nil {
+10 -10
View File
@@ -96,10 +96,10 @@ func NewWriter(w io.Writer) Writer {
}
}
func WriteDir(w io.Writer, listing Listing) error {
func WriteDir(w io.Writer, dir Directory) error {
dw := NewWriter(w)
for _, d := range listing.Entries {
for _, d := range dir.Entries {
if err := dw.WriteEntry(d); err != nil {
return err
}
@@ -108,25 +108,25 @@ func WriteDir(w io.Writer, listing Listing) error {
return nil
}
func ReadDir(r io.Reader) (Listing, error) {
func ReadDir(r io.Reader) (Directory, error) {
var err error
s := bufio.NewScanner(r)
if !s.Scan() {
return Listing{}, fmt.Errorf("empty file")
return Directory{}, fmt.Errorf("empty file")
}
if !bytes.Equal(s.Bytes(), header) {
return Listing{}, fmt.Errorf("invalid header: expected '%v' got '%v'", header, s.Bytes())
return Directory{}, fmt.Errorf("invalid header: expected '%v' got '%v'", header, s.Bytes())
}
l := Listing{}
l := Directory{}
for s.Scan() {
line := s.Bytes()
var v serializedDirectoryEntryV1
if err := json.Unmarshal(line, &v); err != nil {
return Listing{}, nil
return Directory{}, nil
}
e := &Entry{}
@@ -135,18 +135,18 @@ func ReadDir(r io.Reader) (Listing, error) {
e.GroupID = v.GroupID
e.ObjectID, err = cas.ParseObjectID(v.ObjectID)
if err != nil {
return Listing{}, nil
return Directory{}, nil
}
m, err := strconv.ParseInt(v.Mode, 8, 16)
if err != nil {
return Listing{}, nil
return Directory{}, nil
}
e.Mode = int16(m)
e.ModTime = v.ModTime
e.Type = EntryType(v.Type)
if e.Type == EntryTypeFile {
if v.FileSize == nil {
return Listing{}, fmt.Errorf("missing file size")
return Directory{}, fmt.Errorf("missing file size")
}
e.Size = *v.FileSize
+1 -1
View File
@@ -1,2 +1,2 @@
// Package storage implementats repositories for connecting to various types of storage backends.
// Package storage implements repositories for connecting to various types of storage backends.
package storage