2010-08-21 5 views
3

У меня есть прототип сервера [0], который делает os.walk() [1] для каждого запроса, который делает клиент [0].os.walk() кеширование/ускорение

Я в настоящее время изучает способы:

  • кэширования этой информации в памяти,
  • ускорения запросов, и
  • , мы надеемся, что позволяет для расширения в хранения метаданных и сохранение данных в дальнейшем.

Я нахожу SQL complicated для древовидных структур, поэтому я думал, я хотел бы получить несколько советов, прежде чем на самом деле передаванием SQLite

Есть ли кросс-платформенный, встраиваемый или ножки пучка в состоянии базы данных не-SQL, которые могут быть способный обрабатывать данные такого рода?

  • У меня есть небольшой (10k-100k файлов) список.
  • У меня очень небольшое количество соединений (возможно, 10-20).
  • Я хочу иметь возможность масштабирования для обработки метаданных.

[0] сервер и клиент на самом деле тот же кусок программного обеспечения, это P2P приложения, который предназначен для обмена файлами по локальной доверенной сети с вне основного сервера, используя zeroconf для обнаружения и витой для почти все остальное

[1] время запроса в настоящее время 1.2S с os.walk() на 10000 файлов

Вот соответствующая функция в моем коде Python, что делает ходьбу:

def populate(self, string): 
    for name, sharedir in self.sharedirs.items(): 
     for root, dirs, files, in os.walk(sharedir): 
      for dir in dirs: 
       if fnmatch.fnmatch(dir, string): 
        yield os.path.join(name, *os.path.join(root, dir)[len(sharedir):].split("/")) 
      for file in files: 
       if fnmatch.fnmatch(file, string): 
        yield os.path.join(name, *os.path.join(root, ile)[len(sharedir):].split("/")) 
+0

У вас есть небольшое количество похожих запросов от разных клиентов или у вас есть много вариантов? В первом случае может иметь смысл просто кэшировать ответ для каждого запроса. – data

+1

И в случае, если вы не знаете об этом: существует реализация libfam для python, позволяющая кэшировать структуру, не рискуя ее устаревать – data

+0

спасибо данные Я обновил свое сообщение, чтобы отразить ваш вопрос (очень небольшое количество подключений, возможно, 10-20), и я посмотрю на libfam, а также спасибо –

ответ

0

Вы посмотрели MongoDB? Как насчет mod_python? mod_python должен позволить вам сделать ваш os.walk() и просто сохранить данные в структурах данных Python, так как сценарий является постоянным между соединениями.

+0

- это MongoDB, способный легко расслоивать?, извините, я не уверен, почему вы предлагая mod_python? не ограничивается ли HTTP? –

3

Вам не нужно сохранять древовидную структуру - на самом деле, ваш код занят disantling естественная древовидная структура дерева каталогов в линейную последовательность, так зачем вам нужно перезапускать с дерева? время?

Похоже, что вам нужно, это просто упорядоченная последовательность:

i X result of os.path.join for X 

где X, строка, имена либо файла или каталога (вы относиться к ним как раз то же самое), я это постепенно увеличивающиеся целое число (для сохранения порядка), а столбец результатов, также строка, является результатом os.path.join(name, *os.path.join(root, & c.

Это, безусловно, легко установить в таблицу SQL!

Чтобы создать таблицу в первый раз, просто удалите охранник if fnmatch.fnmatchstring аргумента) из вашей функции заселить, дают реж или файл до результата os.path.join и использовать cursor.executemany сохранить enumerate (или используйте самоинструментальный столбец, ваш выбор).Чтобы использовать таблицу, populate становится по существу:

select result from thetable where X LIKE '%foo%' order by i 

где string является foo.

+0

Спасибо за ответ, как бы вы сказали, измените каталог? поэтому все дети модифицированы? –

+1

@ Даниэль, извините, этот новый вопрос не в силе, похоже, не имеет ничего общего с вашим оригинальным - и я понятия не имею, что вы имеете в виду (и в комментариях нет смысла уточнять - никакого кода и т. Д.). Почему бы не закрыть этот вопрос, на который я ответил, и открыть другой для вашей новой, другой проблемы? «Один вопрос на вопрос» кажется разумной и разумной политикой для меня. –

+0

Извините, может быть, мне нужно уточнить, вы предоставили структуру данных и способ добавления данных в структуру. но я вижу проблемы с обновлением данных, когда специально, когда каталог переименован или перемещен, вам придется пройти через всю структуру и сопоставить (используя LIKE) в столбце 3 для каждого файла в этом каталоге, а затем обновить его по сравнению с первым примером в ссылке, которую я предоставил, которая требовала бы только изменения одного узла. Я просто хотел, чтобы вы решили эту проблему? –

3

Сначала я неправильно понял вопрос, но я думаю, что у меня есть решение сейчас (и в значительной степени отличается от моего другого ответа, чтобы гарантировать новый). В основном, вы выполняете обычный запрос при первом запуске в каталоге, но сохраняете полученные значения. Во второй раз вы просто возвращаете эти сохраненные значения. Я завернул вызов os.walk(), потому что он короткий, но вы можете так же легко обернуть ваш генератор в целом.

cache = {} 
def os_walk_cache(dir): 
    if dir in cache: 
     for x in cache[ dir ]: 
     yield x 
    else: 
     cache[ dir ] = [] 
     for x in os.walk(dir): 
     cache[ dir ].append(x) 
     yield x 
    raise StopIteration() 

Я не уверен, ваши требования к памяти, но вы можете рассмотреть периодически вычищать cache.

+0

хорошо, что в прецеденте будет только 1-10 очень больших каталогов Не уверен, что дерево каталогов на самом деле займет много памяти, поэтому я рассматривал механизм базы данных, потому что он позаботится об оптимизации памяти и сохранении когда мне это нужно –