改进gspath缓存数据结构

This commit is contained in:
John
2018-11-23 16:45:30 +08:00
parent 5e7e1077a1
commit 38932f306d
4 changed files with 49 additions and 37 deletions

View File

@ -179,9 +179,15 @@ func (r *Response) ServeFileDownload(path string, name...string) {
r.WriteStatus(http.StatusNotFound)
return
}
downloadName := ""
if len(name) > 0 {
downloadName = name[0]
} else {
downloadName = gfile.Basename(path)
}
r.Header().Set("Content-Type", "application/force-download")
r.Header().Set("Accept-Ranges", "bytes")
r.Header().Set("Content-Disposition", fmt.Sprintf(`attachment;filename="%s"`, gfile.Basename(path)))
r.Header().Set("Content-Disposition", fmt.Sprintf(`attachment;filename="%s"`, downloadName))
r.Server.serveFile(r.request, path)
}

View File

@ -23,8 +23,8 @@ import (
// 文件目录搜索管理对象
type SPath struct {
paths *garray.StringArray // 搜索路径,按照优先级进行排序
cache *gmap.StringInterfaceMap // 搜索结果缓存map
paths *garray.StringArray // 搜索路径,按照优先级进行排序
cache *gmap.StringStringMap // 搜索结果缓存map
}
// 文件搜索缓存项
@ -37,7 +37,7 @@ type SPathCacheItem struct {
func New () *SPath {
return &SPath {
paths : garray.NewStringArray(0, 2),
cache : gmap.NewStringInterfaceMap(),
cache : gmap.NewStringStringMap(),
}
}
@ -108,24 +108,22 @@ func (sp *SPath) Add(path string) (realPath string, err error) {
// 给定的name只是相对文件路径找不到该文件时返回空字符串;
// 当给定indexFiles时如果name时一个目录那么会进一步检索其下对应的indexFiles文件是否存在存在则返回indexFile绝对路径
// 否则返回name目录绝对路径。
func (sp *SPath) Search(name string, indexFiles...string) (path string, isDir bool) {
func (sp *SPath) Search(name string, indexFiles...string) (filePath string, isDir bool) {
name = sp.formatCacheName(name)
if v := sp.cache.Get(name); v != nil {
item := v.(*SPathCacheItem)
if len(indexFiles) > 0 && item.isDir {
if v := sp.cache.Get(name); v != "" {
filePath, isDir = sp.parseCacheValue(v)
if len(indexFiles) > 0 && isDir {
if name == "/" {
name = ""
}
for _, file := range indexFiles {
if v := sp.cache.Get(name + "/" + file); v != nil {
item := v.(*SPathCacheItem)
return item.path, item.isDir
if v := sp.cache.Get(name + "/" + file); v != "" {
return sp.parseCacheValue(v)
}
}
}
return item.path, item.isDir
}
return "", false
return
}
// 从搜索路径中移除指定的文件,这样该文件无法给搜索。
@ -177,26 +175,32 @@ func (sp *SPath) nameFromPath(filePath, rootPath string) string {
return name
}
// 按照一定数据结构生成缓存的数据项字符串
func (sp *SPath) makeCacheValue(filePath string, isDir bool) string {
if isDir {
return filePath + "_D_"
}
return filePath + "_F_"
}
// 按照一定数据结构解析数据项字符串
func (sp *SPath) parseCacheValue(value string) (filePath string, isDir bool) {
if value[len(value) - 2 : len(value) - 1][0] == 'F' {
return value[: len(value) - 3], false
}
return value[: len(value) - 3], true
}
// 添加path到缓存中(递归)
func (sp *SPath) addToCache(filePath, rootPath string) {
// 首先添加自身
idDir := gfile.IsDir(filePath)
sp.cache.SetIfNotExist(sp.nameFromPath(filePath, rootPath), func() interface{} {
return &SPathCacheItem {
path : filePath,
isDir : idDir,
}
})
sp.cache.SetIfNotExist(sp.nameFromPath(filePath, rootPath), sp.makeCacheValue(filePath, idDir))
// 如果添加的是目录,那么需要递归添加
if idDir {
if files, err := gfile.ScanDir(filePath, "*", true); err == nil {
for _, path := range files {
sp.cache.SetIfNotExist(sp.nameFromPath(path, rootPath), func() interface{} {
return &SPathCacheItem {
path : filePath,
isDir : gfile.IsDir(path),
}
})
sp.cache.SetIfNotExist(sp.nameFromPath(path, rootPath), sp.makeCacheValue(path, gfile.IsDir(path)))
}
}
}

View File

@ -2,21 +2,24 @@ package main
import (
"fmt"
"gitee.com/johng/gf/g"
"gitee.com/johng/gf/g/os/gspath"
"gitee.com/johng/gf/g/os/gtime"
"time"
)
func main() {
sp := gspath.New()
path := "/Users/john/Workspace"
path := "/Users/john/Temp"
rp, err := sp.Add(path)
fmt.Println(err)
fmt.Println(rp)
fmt.Println(len(sp.AllPaths()))
fmt.Println(sp)
//gtime.SetInterval(5*time.Second, func() bool {
// g.Dump(sp.AllPaths())
// return true
//})
gtime.SetInterval(5*time.Second, func() bool {
g.Dump(sp.AllPaths())
return true
})
select {

View File

@ -1,11 +1,10 @@
package main
import "fmt"
import (
"fmt"
"gitee.com/johng/gf/g/os/gtime"
)
func main() {
s := "我是中国人//"
for _, v := range s {
fmt.Println(v)
}
fmt.Println(s)
fmt.Println(gtime.Now())
}