Btree

Btree

Этот модуль содержит функции работы с B-tree. Код основан на данном проекте.

Ключ может быть: строка, либо целое число. Значение: строка, number, lua объект. Ключи можут быть одновременно обоих типов.

btree = require(“btree”)

Импорт библиотеки

b = btree.new()

Создать объект btree с двумя полями, одно из которых используется в качестве ключа, а второе - значения. Данные хранятся в оперативной памяти.

Агрументы: нет. Возвращает: объект B-tree.

b = btree.load(filename)

Создать объект btree с двумя полями, одно из которых используется в качестве ключа, а второе - значения, используя данные из файла. Данные хранятся в оперативной памяти.

Агрументы:

  • filename: имя файла; строка. Возвращает: объект B-tree.

Далее идут методы объекта.

size = b:size()

Возвращает количество записей.

Агрументы: нет. Возвращает: число; количество записей.

b:set(key, value)

Добавляет новую пару ключ-значение.

Агрументы:

  • key: строка, либо число; ключ.
  • value: строка, number, lua объект; значение.

Возвращает: ничего или исключение.

value = b:get(key)

Получить значение по ключу.

Агрументы:

  • key: строка, либо число; ключ.

Возвращает: значение, ничего или исключение.

keys = b:keys()

Получить список ключи.

Агрументы: нет

Возвращает: таблицу с ключами или исключение.

b:dump()

Выводит в интерактивную консоль все пары ключ-значение (для отладочных целей).

Агрументы: нет Возвращает: ничего.

value = b:del(key)

Удалить значение по ключу (и получить копию).

Агрументы:

  • key: строка, либо число; ключ.

Возвращает: значение, ничего или исключение.

b:iter(function(key, value) … end)

Итератор по ключам.

Агрументы:

  • Функция с параметрами ключ-значения.

Возвращает: ничего.

b:iter(function(key, value)
    if type(key) == "string" then
        print(string.format("Key (string): %s -> %s", key, tostring(value)))
    elseif type(key) == "number" then
        print(string.format("Key (number): %d -> %s", key, tostring(value)))
    else
        print(string.format("Key (unknown): %s -> %s", tostring(key), tostring(value)))
    end
end)

table = b:to_table()

Экспортирует данные в виде таблицы.

Агрументы: нет Возвращает: таблица или исключение.

b:from_table(table)

Загружет данные из таблицы.

Агрументы:

  • table: таблица. Возвращает: ничего или исключение.

b:save(filename)

Агрументы:

  • filename строка; имя файла.

Возвращает: ничего или исключение.

Данная функция сохраняет только базовые типы данных (строки и числа). Если вы хотите сохранить более сложную структуру, использующую комплексные lua-типы, можно воспользоваться модулем cjson.

Пример:

btree = require "btree"
cjson = require "cjson"

b = btree.new()
b:set(1, "a")
b:set(3, {name="BANANA", color="Yellow"})

-- сериализация
s = cjson.encode(b:to_table())

-- загрузка
e = btree.new()
e:from_table(cjson.decode(s))

Если ключи будут разнотипными (одновременно строки и числа), то cjson приведет все к строкам. Если такое поведение нежелательно, то можно воспользоваться следующим рецептом.

btree = require "btree"
cjson = require "cjson"

function save_btree(tree, filename)
    local data = {}

    tree:iter(function(key, value)
        if type(value) == "table" then
            data[key] = { type = "table", value = value }
        else
            data[key] = { type = type(value), value = value }
        end
    end)

    local json_str = cjson.encode(data)

    local file, err = io.open(filename, "w")
    if not file then
        error("Не удалось открыть файл для записи: " .. err)
    end

    file:write(json_str)
    file:close()
end


function load_btree(filename)
    local file, err = io.open(filename, "r")
    if not file then
        error("Не удалось открыть файл для чтения: " .. err)
    end

    local json_str = file:read("*a")
    file:close()

    local data = cjson.decode(json_str)
    if not data then
        error("Ошибка при декодировании JSON: " .. (decode_err or "неизвестная ошибка"))
    end


    local tree = btree.new()

    for key, entry in pairs(data) do
        if type(entry) ~= "table" or not entry.type or entry.value == nil then
            error("Неверная структура данных в JSON")
        end

        local value = entry.value

        if entry.type == "number" then
            value = tonumber(entry.value)
        end

        tree:set(key, value)
    end

    return tree
end