Как быстро удалить несколько элементов из файлового архива Klepto? - PullRequest
0 голосов
/ 14 февраля 2019

Я использую архив Klepto для индексации спецификаций файлов в дереве папок.После сканирования дерева я хочу быстро удалить ссылки на удаленные файлы.Но просто удалить элемент один за другим из файлового архива очень медленно.Есть ли способ синхронизировать изменения в архиве или удалить сразу несколько ключей?(Метод 'sync' появляется только для добавления новых элементов)

Полезный ответ @Mike Mckerns на этот вопрос касается только удаления одного элемента: Сохранение и редактирование Python с помощью Klepto

Использование files.sync () или files.dump () появляется только для добавления данных из кэша, а не для синхронизации удалений.Есть ли способ удалить ключи из кэша, а затем синхронизировать эти изменения сразу.Отдельные удаления слишком медленные.

Вот рабочий пример:

from klepto.archives import *
import os

class PathIndex:
    def __init__(self,folder):
        self.folder_path=folder
        self.files=file_archive(self.folder_path+'/.filespecs',cache=False)
        self.files.load() #load memory cache

    def list_directory(self):
        self.filelist=[]
        for folder, subdirs, filelist in os.walk(self.folder_path): #go through every subfolder in a folder
            for filename in filelist: #now through every file in the folder/subfolder
                self.filelist.append(os.path.join(folder, filename))

    def scan(self):
        self.list_directory()
        for path in self.filelist:
            self.update_record(path)
        self.files.dump() #save to file archive

    def rescan(self):
        self.list_directory() #rescan original disk
        deletedfiles=[]

        #code to ck for modified files etc            
        #check for deleted files
        for path in self.files:
            try:
                self.filelist.remove(path)  #self.filelist - disk files - leaving list of new files
            except ValueError:
                deletedfiles.append(path)

        #code to add new files, the files left in self.filelist
        for path in deletedfiles:
            self.delete_record(path)
        #looking to here sync modified index from modifed to disk

    def update_record(self,path):
        self.files[path]={'size':os.path.getsize(path),'modified':os.path.getmtime(path)}
        #add other specs - hash of contents etc.

    def delete_record(self,path):
        del(self.files[path]) #delete from the memory cache
        #this next line slows it all down
        del(self.files.archive[path]) #delete from the disk cache

#usage
_index=PathIndex('/path/to/root')
_index.scan()
#delete, modify some files
_index.rescan()

1 Ответ

0 голосов
/ 15 февраля 2019

Понятно ... Вы действительно обеспокоены скоростью удаления одной записи за раз из file_archive.

Хорошо, я согласен.Использование __delitem__ или pop на file_archive немного жестоко, если вы хотите удалить несколько записей.Замедление происходит из-за file_archive необходимости загружать и перезаписывать весь файловый архив для каждого удаляемого ключа.Это не относится к dir_archive или многим другим архивам ... но для file_archive это так.Так что это должно быть исправлено ...

ОБНОВЛЕНИЕ: Я добавил новый метод, который должен позволять более быстрое удаление указанных ключей ...

>>> import klepto as kl
>>> ar = kl.archives.file_archive('foo.pkl')
>>> ar['a'] = 1
>>> ar['b'] = 2
>>> ar['c'] = 3
>>> ar['d'] = 4
>>> ar['e'] = 5
>>> ar.dump()
>>> ar.popkeys(list('abx'), None)
[1, 2, None]
>>> ar.sync(clear=True)
>>> ar
file_archive('foo.pkl', {'c': 3, 'e': 5, 'd': 4}, cached=True)
>>> ar.archive
file_archive('foo.pkl', {'c': 3, 'e': 5, 'd': 4}, cached=False)

Ранее(то есть в выпущенных версиях), вы можете дешево pop ключи, которые вы хотите из локального кэша, а затем сделать ar.sync(clear=True), чтобы удалить связанные ключи в архиве.Однако для этого необходимо, чтобы у вас были все ключи, которые вы хотите сохранить в памяти.Таким образом, вместо загрузки всех ключей в память, теперь вы можете (по крайней мере, в версии, которая скоро выйдет) сделать popkeys как в кеше, так и / или в архиве, чтобы удалить любые ненужные ключи из любого из них.

...