MicroPython:Библиотеки/btree

Материал из Онлайн справочника
Перейти к навигации Перейти к поиску

Перевод: Максим Кузьмин (Cubewriter) Контакты:</br>* Skype: cubewriter</br>* E-mail: cubewriter@gmail.com</br>* Максим Кузьмин на freelance.ru
Проверка/Оформление/Редактирование: Мякишев Е.А.


Модуль btree – простая база данных BTree[1]

В модуле btree реализована простая база данных типа «ключ-значение», использующая внешнюю память (дисковые файлы или, в общем случае, объекты stream с произвольным доступом). Ключи отсортированы и хранятся в базе данных, и помимо возможности извлекать значение по заданному ключу, эта база данных также поддерживает упорядоченное сканирование диапазона (т.е. извлечение значений по ключам заданного диапазона). Что касается интерфейса приложения, то принцип работы базы данных BTree очень похож на стандартный тип данных dict, но с одним большим отличием – и ключи, и значения должны быть объектами bytes (то есть, если вам надо будет сохранить объекты других типов, их сначала надо будет сериализировать в bytes).

Модуль btree основан на популярной библиотеке BerkelyDB (версия 1.xx).

Пример:

import btree

# Во-первых, нам надо открыть поток с базой данных.
# Обычно это файл, но может быть и резидентная база данных,
# использующая uio.BytesIO, RAW-раздел во flash-памяти и т.д.
# Обычно вам надо либо создать файл базы данных, либо открыть его.
# Код ниже именно за это и отвечает.
# НЕ ОТКРЫВАЙТЕ базу данных при помощи режима доступа "a+b".
try:
    f = open("mydb", "r+b")
except OSError:
    f = open("mydb", "w+b")

# Теперь открываем саму базу данных.
db = btree.open(f)

# Добавленные ключи будут отсортированы внутри базы данных.
db[b"3"] = b"three"
db[b"1"] = b"one"
db[b"2"] = b"two"

# Предположительно, все изменения будут кэшироваться в памяти,
# разве что они не будут явно сброшены с помощью функции flush()
# или если база данных не будет закрыта.
# Используем flush() на базе данных в конце каждой «транзакции».
db.flush()

# Печатаем b'two'.
print(db[b"2"])

# Делаем итерацию по отсортированным ключам в базе данных,
# начиная с b"2", пока не достигнем конца базы данных.
# Возвращаем только значения.
# Аргументы, передаваемые методу values() – это ключи.
# Печатаем:
#   b'two'
#   b'three'
for word in db.values(b"2"):
    print(word)

del db[b"2"]

# Больше не «true», печатаем «false»:
print(b"2" in db)

# Печатаем:
#  b"1"
#  b"3"
for key in db:
    print(key)

db.close()

# Не забываем закрыть поток!
f.close()

Функции

  • btree.open(stream, *, flags=0, pagesize=0, cachesize=0, minkeypage=0) – открываем базу данных из потока с произвольным доступом (вроде открытого файла). Все аргументы – опциональные и именованные. С их помощью можно менять менять продвинутые настройки работы базы данных (большинству пользователей они не понадобятся).
    • flags – в данный момент не используется.
    • pagesize – размер страницы, используемый в нодах BTree. Диапазон допустимых значений: 512-65536. Если задать в этом аргументе «0», здесь будет автоматически задано значение по умолчанию, соответствующее используемому порту – оно уже оптимизировано под производительность и/или использование памяти этого порта.
    • cashesize – рекомендуемый размер кэша памяти в байтах. Если вы работаете с платой, у которой много памяти, использование большого значения в этом аргументе может улучшить производительность этой платы. Принцип работы кэша таков: система не выделяет сразу память под весь кэш; вместо этого буфер памяти выделяется только при получении доступа к новой странице – пока не будет достигнуто значение в cachesize. Затем эти буферы начинают работать по принципу «вытеснение давно неиспользуемых» (LRU или «least recently used»). Если нужно, можно выделить память и под дополнительные буферы (например, если база данных содержит большие ключи и/или значения). Память, выделенная под эти выделенные буферы памяти для кэша, не вычищается.
    • minkeypage – минимальное количество ключей, хранящихся на одной странице. Значение по умолчанию «0» эквивалентно «2».

Возвращает объект BTree, в котором реализован протокол словаря (набор методов) и несколько дополнительных методов, описанных ниже.

Методы

  • btree.close() – закрывает базу данных. После завершения работы с базой данных ее обязательно нужно закрыть, т.к. в кэше могут по-прежнему остаться незаписанные данные. Помните, что это не закрывает нижележащий потоковый объект, с помощью которого была открыта база данных – этот поток нужно закрывать отдельно (что тоже обязательно, чтобы данные в буфере были гарантированно сброшены с помощью flush() в нижележащую память).
  • btree.flush() – сбрасывает все данные кэша в нижележащий потоковый объект.
  • btree.__getitem__(key), btree.get(key, default=None, /), btree.__setitem__(key, val), btree.__detitem__(key) и btree.__contains__(key) – стандартные словарные методы.
  • btree.__iter__() – с помощью этого метода выполняется прямая итерация объекта BTree (как это делается со словарем), чтобы получить упорядоченный доступ ко всем ключам.
  • btree.keys([start_key[, end_key[, flags]]]), btree.values([start_key[, end_key[, flags]]]) и btree.items([start_key[, end_key[, flags]]]) – эти методы похожи на стандартные словарные методы, но также могут принимать опциональные параметры, чтобы вы могли делать итерацию не только по всей базе данных, но и по некоторому диапазону ключей. Во всех трех методах аргументы start_key и end_key отвечают за ключи. К примеру, метод values() будет делать итерацию по значениям, соответствующим заданному диапазону ключей. Если задать None в аргументе start_key, это будет значить «с первого ключа», а если не задать аргумента end_key или тоже задать в нем None, это будет значить «до конца базы данных». По умолчанию значение в start_key будет входить в итерируемый диапазон, а значение в end_key – нет, и если вам нужно, чтобы значение end_key входило в него, в аргументе flags нужно задать значение btree.INCL. Если вам нужно сделать итерацию ключей в порядке по убыванию, задайте в аргументе flags значение btree.DESC. В аргументе flags можно поместить несколько значений по принципу логического ИЛИ.

Константы

  • btree.INCL – флаг для методов keys(), values() и items(), с помощью которого задается, нужно ли включить в итерируемый диапазон значение в аргументе end_key.
  • btree.DESC – флаг для методов keys(), values() и items(), с помощью которого задается, что сканирование по ключам должно быть выполнено в порядке по убыванию.



См.также

Ссылки на полезные ресурсы

Внешние ссылки