Browse Source

initial commit

Simon Watson 5 months ago
commit
d78c8c0bac
3 changed files with 105 additions and 0 deletions
  1. 98 0
      fakedu.go
  2. 5 0
      go.mod
  3. 2 0
      go.sum

+ 98 - 0
fakedu.go

@@ -0,0 +1,98 @@
+package main
+
+import (
+	"fmt"
+	"os"
+	"path/filepath"
+	"sync"
+)
+
+// go-fakedu - toy approximation of the du (disk  usage)
+// toy program to learn go concurrency structures
+
+type FileInfo struct {
+	path string
+	info os.FileInfo
+}
+
+type SafeArraySlice struct {
+	m    sync.Mutex
+	data []int64
+}
+
+func NewSafeIntArraySlice() *SafeArraySlice {
+	return &SafeArraySlice{
+		m:    sync.Mutex{},
+		data: make([]int64, 100),
+	}
+}
+
+func (a *SafeArraySlice) AppendIntArraySlice(i int64) {
+	a.m.Lock()
+	defer a.m.Unlock()
+	a.data = append(a.data, i)
+}
+
+func enumFiles(dir string) {
+	fileCh := make(chan FileInfo)
+	errCh := make(chan error, 1) // Buffered channel to prevent blocking
+	var wg sync.WaitGroup
+
+	file_size_storage := NewSafeIntArraySlice()
+
+	// Start a goroutine for walking the file tree
+	go func() {
+		// Send any errors to the errCh channel
+		errCh <- filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
+			if err != nil {
+				return err
+			}
+			if !info.IsDir() {
+				fileCh <- FileInfo{path, info}
+			}
+			return nil
+		})
+		close(fileCh) // Close the fileCh channel after walking is done
+	}()
+
+	// Start a goroutine to process files
+	go func() {
+		for path := range fileCh {
+			wg.Add(1)
+			go func(fInfo FileInfo) {
+				defer wg.Done()
+				// Process file (e.g., read, hash, etc.)
+				fmt.Println(fInfo.path, fInfo.info.Size())
+				file_size_storage.AppendIntArraySlice(fInfo.info.Size())
+
+			}(path)
+		}
+		wg.Wait()
+		close(errCh) // Close the errCh channel after all processing is done
+	}()
+
+	// Check for errors from filepath.Walk
+	if err := <-errCh; err != nil {
+		fmt.Println("Error walking the file tree:", err)
+		return
+	}
+
+	// Not getting a lock here as by now we know
+	// that nothing is currently accessing this  slice
+	var size int64 = 0
+	for _, value := range file_size_storage.data {
+		size = size + value
+	}
+
+	fmt.Println("Total size: ", float32(size)/(1<<20), "MBs")
+}
+
+func main() {
+	args := os.Args
+	if len(args) < 2 {
+		fmt.Println("Must provide path to directory")
+		os.Exit(1)
+	}
+
+	enumFiles(args[1])
+}

+ 5 - 0
go.mod

@@ -0,0 +1,5 @@
+module go-fake-du
+
+go 1.21
+
+require github.com/inhies/go-bytesize v0.0.0-20220417184213-4913239db9cf // indirect

+ 2 - 0
go.sum

@@ -0,0 +1,2 @@
+github.com/inhies/go-bytesize v0.0.0-20220417184213-4913239db9cf h1:FtEj8sfIcaaBfAKrE1Cwb61YDtYq9JxChK1c7AKce7s=
+github.com/inhies/go-bytesize v0.0.0-20220417184213-4913239db9cf/go.mod h1:yrqSXGoD/4EKfF26AOGzscPOgTTJcyAwM2rpixWT+t4=