Refactor Sizer internals.

This commit is contained in:
Blallo 2019-05-16 21:02:26 +02:00
parent 9e0140b3e1
commit 9dd7784a60
No known key found for this signature in database
GPG key ID: 0CBE577C9B72DC3F

View file

@ -116,85 +116,60 @@ func ls(path string) ([]string, error) {
return content, nil
}
func runThrough(i *INode, ch chan int64, report chan statusReport, content []string) {
Console.Debugln("Entering:", i.Path)
for _, filepath := range content {
f, err := os.Lstat(filepath)
if err != nil {
report <- statusReport{path: i.Path, err: err}
}
switch mode := f.Mode(); {
case mode.IsDir():
Console.Debugln(filepath, "is a directory")
dirINode := NewINode(FileTypes["dir"], f.Size(), filepath)
i.Children.Append(dirINode)
ch <- f.Size()
go dirINode.walkDir(report)
case mode.IsRegular():
Console.Debugln(filepath, "is a regular file")
fileINode := NewINode(FileTypes["file"], f.Size(), filepath)
i.Children.Append(fileINode)
ch <- f.Size()
}
func (i *INode) size(wg *sync.WaitGroup) {
//Console.Debugln(i.Path)
i.Children.safe.Lock()
defer i.Children.safe.Unlock()
var wgIn sync.WaitGroup
for _, child := range i.Children.Elements {
wg.Add(1)
go child.walk(&wgIn)
}
wgIn.Wait()
for _, child := range i.Children.Elements {
i.Size += child.Size
wg.Done()
}
}
func (i *INode) walk(wg *sync.WaitGroup) {
children, err := ls(i.Path)
if err != nil {
Console.Println(err)
wg.Done()
return
}
for _, child := range children {
//Console.Debugln("Parent:", i.Path, "- Child:", child)
kind, size, err := IdentifyType(child)
if err != nil {
Console.Println(child, ":", err)
}
childINode := NewINode(kind, size, child)
i.Children.Append(childINode)
switch {
case kind == DirType:
//Console.Debugln("Size on dir:", child)
wg.Add(1)
childINode.size(wg)
case kind == FileType:
Console.Debugln("Filesize:", child, "-", size)
childINode.Size = size
default:
Console.Debugln(filepath, "is NOT a regular file")
var otherINode *INode
inodeType, err := IdentifyType(filepath)
if err != nil {
if err != ErrNotIdenfiedType {
report <- statusReport{path: filepath, err: err}
return // Is this necessary?
}
otherINode = NewINode(-1, 0, filepath)
} else {
otherINode = NewINode(inodeType, 0, filepath)
}
i.Children.Append(otherINode)
//Console.Debugln("Unknown:", child)
childINode.Size = 0
}
}
report <- statusReport{path: i.Path, err: nil}
wg.Done()
}
func (i *INode) walkDir(reportUp chan statusReport) {
ch := make(chan int64, 1)
report := make(chan statusReport, 1)
content, err := ls(i.Path)
if err != nil {
Console.Fatal(err)
}
go runThrough(i, ch, report, content)
for {
select {
case size := <-ch:
i.Size += size
case status := <-report:
Console.Debugf("[%s] Report from: %s\n", i.Path, status.path)
if status.err != nil {
Console.Debugln("Sending error. Path:", status.path, "- Err:", status.err)
reportUp <- status
}
if status.err == nil {
Console.Debugf("[%s] Received -> %s - Closing channel...\n",
i.Path, status.path)
reportUp <- status
close(reportUp)
return
}
}
}
}
// Sizer is the main entrypoint for the computation of the size of a directory.
func (i *INode) Sizer() {
if i.Kind == FileTypes["file"] {
Console.Println("This is not a directory!")
return
}
report := make(chan statusReport)
go i.walkDir(report)
for r := range report {
if r.err != nil {
Console.Fatalf("%s: %s", r.path, r.err)
}
Console.Printf("%s: %d", i.Path, i.Size)
}
var wg sync.WaitGroup
wg.Add(1)
i.walk(&wg)
wg.Wait()
Console.Println(i.Size)
}