Как быстро удалить несколько элементов из файлового архива Klepto?
Я использую архив 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 ответ
Я вижу... вы действительно обеспокоены скоростью удаления одной записи за раз из 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
как в кеше, так и / или в архиве, чтобы удалить ненужные ключи.