cache directory contents in memory

Mentioned in #92.
This commit is contained in:
Gokcehan 2017-11-19 01:25:41 +03:00
parent accb61dad1
commit 9ac32fc850
2 changed files with 54 additions and 55 deletions

106
nav.go
View File

@ -139,7 +139,7 @@ type dir struct {
fi []*file fi []*file
} }
func newDir(path string) *dir { func newDir(path string, height int) *dir {
fi, err := readdir(path) fi, err := readdir(path)
if err != nil { if err != nil {
log.Printf("reading directory: %s", err) log.Printf("reading directory: %s", err)
@ -150,7 +150,7 @@ func newDir(path string) *dir {
fi: fi, fi: fi,
} }
dir.sort() dir.sort(height)
return dir return dir
} }
@ -168,12 +168,16 @@ func (dir *dir) renew(height int) {
dir.fi = fi dir.fi = fi
dir.sort() dir.sort(height)
dir.load(dir.ind, dir.pos, height, name) dir.find(dir.ind, dir.pos, height, name)
} }
func (dir *dir) sort() { func (dir *dir) sort(height int) {
if len(dir.fi) != 0 && dir.ind < len(dir.fi) {
defer dir.find(dir.ind, dir.pos, height, dir.fi[dir.ind].Name())
}
switch gOpts.sortby { switch gOpts.sortby {
case "natural": case "natural":
sortFilesStable(dir.fi, func(i, j int) bool { sortFilesStable(dir.fi, func(i, j int) bool {
@ -211,7 +215,7 @@ func (dir *dir) sort() {
} }
} }
func (dir *dir) load(ind, pos, height int, name string) { func (dir *dir) find(ind, pos, height int, name string) {
if len(dir.fi) == 0 { if len(dir.fi) == 0 {
dir.ind, dir.pos = 0, 0 dir.ind, dir.pos = 0, 0
return return
@ -236,27 +240,44 @@ func (dir *dir) load(ind, pos, height int, name string) {
} }
type nav struct { type nav struct {
dirs []*dir dirs []*dir
inds map[string]int dirCache map[string]*dir
poss map[string]int marks map[string]int
names map[string]string saves map[string]bool
marks map[string]int markInd int
saves map[string]bool height int
markInd int search string
height int
search string
} }
func getDirs(wd string, height int) []*dir { func newNav(height int) *nav {
wd, err := os.Getwd()
if err != nil {
log.Printf("getting current directory: %s", err)
}
nav := &nav{
dirCache: make(map[string]*dir),
marks: make(map[string]int),
saves: make(map[string]bool),
markInd: 0,
height: height,
}
nav.getDirs(wd)
return nav
}
func (nav *nav) getDirs(wd string) {
var dirs []*dir var dirs []*dir
for curr, base := wd, ""; !isRoot(base); curr, base = filepath.Dir(curr), filepath.Base(curr) { for curr, base := wd, ""; !isRoot(base); curr, base = filepath.Dir(curr), filepath.Base(curr) {
dir := newDir(curr) dir := nav.load(curr)
for i, f := range dir.fi { for i, f := range dir.fi {
if f.Name() == base { if f.Name() == base {
dir.ind = i dir.ind = i
edge := min(gOpts.scrolloff, len(dir.fi)-dir.ind-1) edge := min(gOpts.scrolloff, len(dir.fi)-dir.ind-1)
dir.pos = min(i, height-edge-1) dir.pos = min(i, nav.height-edge-1)
break break
} }
} }
@ -267,27 +288,7 @@ func getDirs(wd string, height int) []*dir {
dirs[i], dirs[j] = dirs[j], dirs[i] dirs[i], dirs[j] = dirs[j], dirs[i]
} }
return dirs nav.dirs = dirs
}
func newNav(height int) *nav {
wd, err := os.Getwd()
if err != nil {
log.Printf("getting current directory: %s", err)
}
dirs := getDirs(wd, height)
return &nav{
dirs: dirs,
inds: make(map[string]int),
poss: make(map[string]int),
names: make(map[string]string),
marks: make(map[string]int),
saves: make(map[string]bool),
markInd: 0,
height: height,
}
} }
func (nav *nav) renew(height int) { func (nav *nav) renew(height int) {
@ -306,9 +307,19 @@ func (nav *nav) renew(height int) {
} }
} }
func (nav *nav) load(path string) *dir {
dir, ok := nav.dirCache[path]
if !ok {
dir = newDir(path, nav.height)
dir.ind, dir.pos = 0, 0
nav.dirCache[path] = dir
}
return dir
}
func (nav *nav) sort() { func (nav *nav) sort() {
for _, d := range nav.dirs { for _, d := range nav.dirs {
d.sort() d.sort(nav.height)
} }
} }
@ -357,13 +368,6 @@ func (nav *nav) updir() error {
dir := nav.currDir() dir := nav.currDir()
nav.inds[dir.path] = dir.ind
nav.poss[dir.path] = dir.pos
if len(dir.fi) != 0 {
nav.names[dir.path] = dir.fi[dir.ind].Name()
}
nav.dirs = nav.dirs[:len(nav.dirs)-1] nav.dirs = nav.dirs[:len(nav.dirs)-1]
if err := os.Chdir(filepath.Dir(dir.path)); err != nil { if err := os.Chdir(filepath.Dir(dir.path)); err != nil {
@ -381,9 +385,7 @@ func (nav *nav) open() error {
path := curr.Path path := curr.Path
dir := newDir(path) dir := nav.load(path)
dir.load(nav.inds[path], nav.poss[path], nav.height, nav.names[path])
nav.dirs = append(nav.dirs, dir) nav.dirs = append(nav.dirs, dir)
@ -420,9 +422,7 @@ func (nav *nav) cd(wd string) error {
return fmt.Errorf("cd: %s", err) return fmt.Errorf("cd: %s", err)
} }
nav.dirs = getDirs(wd, nav.height) nav.getDirs(wd)
// TODO: save/load ind and pos from the map
return nil return nil
} }

3
ui.go
View File

@ -455,8 +455,7 @@ func (ui *ui) loadFile(nav *nav) {
} }
if curr.IsDir() { if curr.IsDir() {
dir := newDir(curr.Path) dir := nav.load(curr.Path)
dir.load(nav.inds[curr.Path], nav.poss[curr.Path], nav.height, nav.names[curr.Path])
ui.dirprev = dir ui.dirprev = dir
} else if curr.Mode().IsRegular() { } else if curr.Mode().IsRegular() {
var reader io.Reader var reader io.Reader