lib/db: Remove index ids when dropping folder (#7200)

This commit is contained in:
Simon Frei 2020-12-21 11:10:59 +01:00 committed by GitHub
parent d904dfa191
commit bd0c9913cf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 33 additions and 0 deletions

View File

@ -102,6 +102,7 @@ type keyer interface {
// index IDs
GenerateIndexIDKey(key, device, folder []byte) (indexIDKey, error)
FolderFromIndexIDKey(key []byte) ([]byte, bool)
// Mtimes
GenerateMtimesKey(key, folder []byte) (mtimesKey, error)
@ -303,6 +304,10 @@ func (k defaultKeyer) GenerateIndexIDKey(key, device, folder []byte) (indexIDKey
return key, nil
}
func (k defaultKeyer) FolderFromIndexIDKey(key []byte) ([]byte, bool) {
return k.folderIdx.Val(binary.BigEndian.Uint32(key[keyPrefixLen+keyDeviceLen:]))
}
type mtimesKey []byte
func (k defaultKeyer) GenerateMtimesKey(key, folder []byte) (mtimesKey, error) {

View File

@ -553,6 +553,26 @@ func (db *Lowlevel) setIndexID(device, folder []byte, id protocol.IndexID) error
return db.Put(key, bs)
}
func (db *Lowlevel) dropFolderIndexIDs(folder []byte) error {
t, err := db.newReadWriteTransaction()
if err != nil {
return err
}
defer t.close()
if err := t.deleteKeyPrefixMatching([]byte{KeyTypeIndexID}, func(key []byte) bool {
keyFolder, ok := t.keyer.FolderFromIndexIDKey(key)
if !ok {
l.Debugf("Deleting IndexID with missing FolderIdx: %v", key)
return true
}
return bytes.Equal(keyFolder, folder)
}); err != nil {
return err
}
return t.Commit()
}
func (db *Lowlevel) dropMtimes(folder []byte) error {
key, err := db.keyer.GenerateMtimesKey(nil, folder)
if err != nil {

View File

@ -419,6 +419,7 @@ func DropFolder(db *Lowlevel, folder string) {
db.dropFolder,
db.dropMtimes,
db.dropFolderMeta,
db.dropFolderIndexIDs,
db.folderIdx.Delete,
}
for _, drop := range droppers {

View File

@ -889,12 +889,19 @@ func (t readWriteTransaction) removeFromGlobal(gk, keyBuf, folder, device, file
}
func (t readWriteTransaction) deleteKeyPrefix(prefix []byte) error {
return t.deleteKeyPrefixMatching(prefix, func([]byte) bool { return true })
}
func (t readWriteTransaction) deleteKeyPrefixMatching(prefix []byte, match func(key []byte) bool) error {
dbi, err := t.NewPrefixIterator(prefix)
if err != nil {
return err
}
defer dbi.Release()
for dbi.Next() {
if !match(dbi.Key()) {
continue
}
if err := t.Delete(dbi.Key()); err != nil {
return err
}