commit d78c8c0bac38331ab3bfbe4850b93f61e11c8d92
Author: Simon Watson <spesk@pm.me>
Date: Tue Dec 5 21:59:54 2023 -0500
initial commit
diff --git a/fakedu.go b/fakedu.go
new file mode 100644
index 0000000..13abb6d
--- /dev/null
+++ b/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])
+}
diff --git a/go.mod b/go.mod
new file mode 100644
index 0000000..1bfba04
--- /dev/null
+++ b/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
diff --git a/go.sum b/go.sum
new file mode 100644
index 0000000..0a5fb3e
--- /dev/null
+++ b/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=