]> Cypherpunks repositories - gostls13.git/commitdiff
os: cache Getwd result as hint for next time
authorRuss Cox <rsc@golang.org>
Thu, 14 Feb 2013 19:21:09 +0000 (14:21 -0500)
committerRuss Cox <rsc@golang.org>
Thu, 14 Feb 2013 19:21:09 +0000 (14:21 -0500)
Avoids the dot-dot-based algorithm on repeated calls
when the directory hasn't changed.

R=golang-dev, iant, bradfitz
CC=golang-dev
https://golang.org/cl/7340043

src/pkg/os/getwd.go

index 81d8fed926eeca8cd54d7972a4897386ba023894..1b22123068dedfd90a757155798024657e033ff4 100644 (file)
@@ -5,9 +5,15 @@
 package os
 
 import (
+       "sync"
        "syscall"
 )
 
+var getwdCache struct {
+       sync.Mutex
+       dir string
+}
+
 // Getwd returns a rooted path name corresponding to the
 // current directory.  If the current directory can be
 // reached via multiple paths (due to symbolic links),
@@ -35,6 +41,17 @@ func Getwd() (pwd string, err error) {
                }
        }
 
+       // Apply same kludge but to cached dir instead of $PWD.
+       getwdCache.Lock()
+       pwd = getwdCache.dir
+       getwdCache.Unlock()
+       if len(pwd) > 0 {
+               d, err := Stat(pwd)
+               if err == nil && SameFile(dot, d) {
+                       return pwd, nil
+               }
+       }
+
        // Root is a special case because it has no parent
        // and ends in a slash.
        root, err := Stat("/")
@@ -88,5 +105,11 @@ func Getwd() (pwd string, err error) {
                // Set up for next round.
                dot = pd
        }
+
+       // Save answer as hint to avoid the expensive path next time.
+       getwdCache.Lock()
+       getwdCache.dir = pwd
+       getwdCache.Unlock()
+
        return pwd, nil
 }