From 9dd7784a60e897898c4a71b868ee0e76ccc95f3f Mon Sep 17 00:00:00 2001 From: Blallo Date: Thu, 16 May 2019 21:02:26 +0200 Subject: [PATCH] Refactor Sizer internals. --- sizer/main.go | 121 ++++++++++++++++++++------------------------------ 1 file changed, 48 insertions(+), 73 deletions(-) diff --git a/sizer/main.go b/sizer/main.go index 2bb9152..f968462 100644 --- a/sizer/main.go +++ b/sizer/main.go @@ -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() - 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) - } } - report <- statusReport{path: i.Path, err: nil} } -func (i *INode) walkDir(reportUp chan statusReport) { - ch := make(chan int64, 1) - report := make(chan statusReport, 1) - content, err := ls(i.Path) +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.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!") + Console.Println(err) + wg.Done() 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) + 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("Unknown:", child) + childINode.Size = 0 } - Console.Printf("%s: %d", i.Path, i.Size) } + wg.Done() +} + +func (i *INode) Sizer() { + var wg sync.WaitGroup + wg.Add(1) + i.walk(&wg) + wg.Wait() + Console.Println(i.Size) }