github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/accounts/keystore/file_cache.go (about) 1 2 //<developer> 3 // <name>linapex 曹一峰</name> 4 // <email>linapex@163.com</email> 5 // <wx>superexc</wx> 6 // <qqgroup>128148617</qqgroup> 7 // <url>https://jsq.ink</url> 8 // <role>pku engineer</role> 9 // <date>2019-03-16 12:09:26</date> 10 //</624342584952623104> 11 12 13 package keystore 14 15 import ( 16 "io/ioutil" 17 "os" 18 "path/filepath" 19 "strings" 20 "sync" 21 "time" 22 23 mapset "github.com/deckarep/golang-set" 24 "github.com/ethereum/go-ethereum/log" 25 ) 26 27 //filecache是在扫描密钥库期间看到的文件的缓存。 28 type fileCache struct { 29 all mapset.Set //从keystore文件夹中设置所有文件 30 lastMod time.Time //上次修改文件时的实例 31 mu sync.RWMutex 32 } 33 34 //scan对给定的目录执行新扫描,与 35 //缓存文件名,并返回文件集:创建、删除、更新。 36 func (fc *fileCache) scan(keyDir string) (mapset.Set, mapset.Set, mapset.Set, error) { 37 t0 := time.Now() 38 39 //列出keystore文件夹中的所有故障 40 files, err := ioutil.ReadDir(keyDir) 41 if err != nil { 42 return nil, nil, nil, err 43 } 44 t1 := time.Now() 45 46 fc.mu.Lock() 47 defer fc.mu.Unlock() 48 49 //迭代所有文件并收集其元数据 50 all := mapset.NewThreadUnsafeSet() 51 mods := mapset.NewThreadUnsafeSet() 52 53 var newLastMod time.Time 54 for _, fi := range files { 55 path := filepath.Join(keyDir, fi.Name()) 56 //跳过文件夹中的任何非关键文件 57 if nonKeyFile(fi) { 58 log.Trace("Ignoring file on account scan", "path", path) 59 continue 60 } 61 //收集所有修改过的文件集 62 all.Add(path) 63 64 modified := fi.ModTime() 65 if modified.After(fc.lastMod) { 66 mods.Add(path) 67 } 68 if modified.After(newLastMod) { 69 newLastMod = modified 70 } 71 } 72 t2 := time.Now() 73 74 //更新跟踪文件并返回三组 75 deletes := fc.all.Difference(all) //删除=上一个-当前 76 creates := all.Difference(fc.all) //创建=当前-上一个 77 updates := mods.Difference(creates) //更新=修改-创建 78 79 fc.all, fc.lastMod = all, newLastMod 80 t3 := time.Now() 81 82 //报告扫描数据并返回 83 log.Debug("FS scan times", "list", t1.Sub(t0), "set", t2.Sub(t1), "diff", t3.Sub(t2)) 84 return creates, deletes, updates, nil 85 } 86 87 //非关键文件忽略编辑器备份、隐藏文件和文件夹/符号链接。 88 func nonKeyFile(fi os.FileInfo) bool { 89 //跳过编辑器备份和Unix样式的隐藏文件。 90 if strings.HasSuffix(fi.Name(), "~") || strings.HasPrefix(fi.Name(), ".") { 91 return true 92 } 93 //跳过其他特殊文件、目录(是,也可以跳过符号链接)。 94 if fi.IsDir() || fi.Mode()&os.ModeType != 0 { 95 return true 96 } 97 return false 98 } 99