os.walk () кэширование / ускорение - PullRequest
3 голосов
/ 21 августа 2010

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

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

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

Iнайти SQL сложный для древовидных структур, поэтому я подумал, что получу несколько советов, прежде чем приступить к фиксации SQLite

Существуют ли какие-либо кроссплатформенные, встраиваемые или связываемые базы данных, отличные от SQL,быть в состоянии обрабатывать такие данные?

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

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

[1] время запроса в настоящее время составляет 1,2 с при os.walk() на 10 000files

Вот моя функция в моем коде 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("/"))

Ответы [ 3 ]

3 голосов
/ 21 августа 2010

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

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

i   X    result of os.path.join for X

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

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

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

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

, где string равно foo.

3 голосов
/ 22 августа 2010

Сначала я неправильно понял вопрос, но думаю, что теперь у меня есть решение (и достаточно отличающееся от моего другого ответа, чтобы дать новый). По сути, вы выполняете обычный запрос при первом запуске ходьбы по каталогу, но сохраняете полученные значения. Во второй раз вы просто выдаете эти сохраненные значения. Я завернул вызов 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 голосов
/ 21 августа 2010

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

...