github.com/2lambda123/git-lfs@v2.5.2+incompatible/locking/cache.go (about) 1 package locking 2 3 import ( 4 "strings" 5 6 "github.com/git-lfs/git-lfs/tools/kv" 7 ) 8 9 const ( 10 // We want to use a single cache file for integrity, but to make it easy to 11 // list all locks, prefix the id->path map in a way we can identify (something 12 // that won't be in a path) 13 idKeyPrefix string = "*id*://" 14 ) 15 16 type LockCache struct { 17 kv *kv.Store 18 } 19 20 func NewLockCache(filepath string) (*LockCache, error) { 21 kv, err := kv.NewStore(filepath) 22 if err != nil { 23 return nil, err 24 } 25 return &LockCache{kv}, nil 26 } 27 28 // Cache a successful lock for faster local lookup later 29 func (c *LockCache) Add(l Lock) error { 30 // Store reference in both directions 31 // Path -> Lock 32 c.kv.Set(l.Path, &l) 33 // EncodedId -> Lock (encoded so we can easily identify) 34 c.kv.Set(c.encodeIdKey(l.Id), &l) 35 return nil 36 } 37 38 // Remove a cached lock by path becuase it's been relinquished 39 func (c *LockCache) RemoveByPath(filePath string) error { 40 ilock := c.kv.Get(filePath) 41 if lock, ok := ilock.(*Lock); ok && lock != nil { 42 c.kv.Remove(lock.Path) 43 // Id as key is encoded 44 c.kv.Remove(c.encodeIdKey(lock.Id)) 45 } 46 return nil 47 } 48 49 // Remove a cached lock by id because it's been relinquished 50 func (c *LockCache) RemoveById(id string) error { 51 // Id as key is encoded 52 idkey := c.encodeIdKey(id) 53 ilock := c.kv.Get(idkey) 54 if lock, ok := ilock.(*Lock); ok && lock != nil { 55 c.kv.Remove(idkey) 56 c.kv.Remove(lock.Path) 57 } 58 return nil 59 } 60 61 // Get the list of cached locked files 62 func (c *LockCache) Locks() []Lock { 63 var locks []Lock 64 c.kv.Visit(func(key string, val interface{}) bool { 65 // Only report file->id entries not reverse 66 if !c.isIdKey(key) { 67 lock := val.(*Lock) 68 locks = append(locks, *lock) 69 } 70 return true // continue 71 }) 72 return locks 73 } 74 75 // Clear the cache 76 func (c *LockCache) Clear() { 77 c.kv.RemoveAll() 78 } 79 80 // Save the cache 81 func (c *LockCache) Save() error { 82 return c.kv.Save() 83 } 84 85 func (c *LockCache) encodeIdKey(id string) string { 86 // Safety against accidents 87 if !c.isIdKey(id) { 88 return idKeyPrefix + id 89 } 90 return id 91 } 92 93 func (c *LockCache) decodeIdKey(key string) string { 94 // Safety against accidents 95 if c.isIdKey(key) { 96 return key[len(idKeyPrefix):] 97 } 98 return key 99 } 100 101 func (c *LockCache) isIdKey(key string) bool { 102 return strings.HasPrefix(key, idKeyPrefix) 103 }