Browse Source

Refactor Sizer internals.

Blallo 5 years ago
parent
commit
9dd7784a60
1 changed files with 45 additions and 70 deletions
  1. 45 70
      sizer/main.go

+ 45 - 70
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)
-	if err != nil {
-		Console.Fatal(err)
+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)
 	}
-	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
-			}
-		}
+	wgIn.Wait()
+	for _, child := range i.Children.Elements {
+		i.Size += child.Size
+		wg.Done()
 	}
 }
 
-// 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!")
+func (i *INode) walk(wg *sync.WaitGroup) {
+	children, err := ls(i.Path)
+	if err != nil {
+		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)
 }