reverse: add single-entry path cache
Speeds up the "ls -lR" benchmark from 2.6 seconds to 2.0.
This commit is contained in:
parent
ef089c9f80
commit
fe1705c55b
@ -82,18 +82,31 @@ func (rfs *ReverseFS) decryptPath(relPath string) (string, error) {
|
|||||||
if rfs.args.PlaintextNames || relPath == "" {
|
if rfs.args.PlaintextNames || relPath == "" {
|
||||||
return relPath, nil
|
return relPath, nil
|
||||||
}
|
}
|
||||||
|
// Check if the parent dir is in the cache
|
||||||
|
cDir := saneDir(relPath)
|
||||||
|
dirIV, pDir := rPathCache.lookup(cDir)
|
||||||
|
if dirIV != nil {
|
||||||
|
cName := filepath.Base(relPath)
|
||||||
|
pName, err := rfs.rDecryptName(cName, dirIV, pDir)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return filepath.Join(pDir, pName), nil
|
||||||
|
}
|
||||||
parts := strings.Split(relPath, "/")
|
parts := strings.Split(relPath, "/")
|
||||||
var transformedParts []string
|
var transformedParts []string
|
||||||
for i := range parts {
|
for i := range parts {
|
||||||
// Start at the top and recurse
|
// Start at the top and recurse
|
||||||
currentCipherDir := filepath.Join(parts[:i]...)
|
currentCipherDir := filepath.Join(parts[:i]...)
|
||||||
currentPlainDir := filepath.Join(transformedParts[:i]...)
|
currentPlainDir := filepath.Join(transformedParts[:i]...)
|
||||||
dirIV := derivePathIV(currentCipherDir, ivPurposeDirIV)
|
dirIV = derivePathIV(currentCipherDir, ivPurposeDirIV)
|
||||||
transformedPart, err := rfs.rDecryptName(parts[i], dirIV, currentPlainDir)
|
transformedPart, err := rfs.rDecryptName(parts[i], dirIV, currentPlainDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
transformedParts = append(transformedParts, transformedPart)
|
transformedParts = append(transformedParts, transformedPart)
|
||||||
}
|
}
|
||||||
return filepath.Join(transformedParts...), nil
|
pRelPath := filepath.Join(transformedParts...)
|
||||||
|
rPathCache.store(cDir, dirIV, saneDir(pRelPath))
|
||||||
|
return pRelPath, nil
|
||||||
}
|
}
|
||||||
|
41
internal/fusefrontend_reverse/rpath_cache.go
Normal file
41
internal/fusefrontend_reverse/rpath_cache.go
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
package fusefrontend_reverse
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
// rPathCacheContainer is a simple one entry path cache. Because the dirIV
|
||||||
|
// is generated deterministically from the directory path, there is no need
|
||||||
|
// to ever invalidate entries.
|
||||||
|
type rPathCacheContainer struct {
|
||||||
|
sync.Mutex
|
||||||
|
// Relative ciphertext path to the directory
|
||||||
|
cPath string
|
||||||
|
// Relative plaintext path
|
||||||
|
pPath string
|
||||||
|
// Directory IV of the directory
|
||||||
|
dirIV []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *rPathCacheContainer) lookup(cPath string) ([]byte, string) {
|
||||||
|
c.Lock()
|
||||||
|
defer c.Unlock()
|
||||||
|
if cPath == c.cPath {
|
||||||
|
//fmt.Printf("HIT %q\n", cPath)
|
||||||
|
return c.dirIV, c.pPath
|
||||||
|
}
|
||||||
|
//fmt.Printf("MISS %q\n", cPath)
|
||||||
|
return nil, ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// store - write entry for "cPath" into the cache
|
||||||
|
func (c *rPathCacheContainer) store(cPath string, dirIV []byte, pPath string) {
|
||||||
|
//fmt.Printf("STORE %q\n", cPath)
|
||||||
|
c.Lock()
|
||||||
|
defer c.Unlock()
|
||||||
|
c.cPath = cPath
|
||||||
|
c.dirIV = dirIV
|
||||||
|
c.pPath = pPath
|
||||||
|
}
|
||||||
|
|
||||||
|
var rPathCache rPathCacheContainer
|
Loading…
x
Reference in New Issue
Block a user