Голанг написать структуру как необработанные данные
Я работаю над базой данных нового типа, используя GO. Одна из вещей, которые я хотел бы сделать, - это иметь распределенный диск, чтобы я мог распределять запросы по нескольким машинам (например, архитектура типа Pi). Это означает построение моих собственных структур на сыром диске.
Моя проблема в том, что я не могу найти пакет GO, который позволил бы мне написать N байтов из указателя на структуру. Все пакеты ввода / вывода ограничивают доступ к [] байтовым фрагментам.
Это хорошо для защиты, но если мне придется буферизовать все через байтовый массив с помощью какой-либо формы кодирования, это замедлит доступ к определенному объекту.
Кто-нибудь получил какие-либо идеи о том, как сделать сырой ввод-вывод? Или мне придется обрабатывать GOB как свою единицу ввода-вывода и нести штраф за кодирование / декодирование?
3 ответа
Первое большое предупреждение: не делайте этого: это не безопасно и не переносимо
Для данной структуры вы можете поразмышлять над ней, чтобы выяснить размер фактической структуры в памяти, а затем небезопасно привести ее к []byte
с помощью unsafe
,
например: (*[in-mem size]byte)(unsafe.Pointer(&mystruct))
Это даст вам что-то C-ish без каких-либо гарантий безопасности или мобильности.
Я процитирую спецификацию Go:
Пакет, использующий небезопасный, должен быть проверен вручную для безопасности типа и не может быть переносимым.
Вы можете найти гораздо больше подробностей в этом посте о разметке Go и Memory, включая все шаги, которые вам необходимы для небезопасной обработки структур как простых байтов.
В целом, интересно изучить, как работает Go на низком уровне, но это абсолютно не то, что нужно делать в вашем случае. Любая реальная инфраструктура данных будет нуждаться в более сложной логике хранения, чем просто выгрузка структур в памяти на диск.
В общем, вы не можете делать необработанный ввод-вывод структуры Go (т.е. memdump). Это потому, что многие вещи в Go содержат указатели, а фактические данные не являются непрерывными в памяти.
Например, такая структура:
type Person struct {
Name string
}
содержит строку, которая в свою очередь содержит указатель на байты строки. Необработанный memdump только выдает указатель.
Решение - сериализация. Это никогда не бывает бесплатным, хотя некоторые реализации делают довольно хорошую работу.
Наиболее близким к тому, что вы описываете, является что-то вроде go-memdump, но я бы не рекомендовал его для производства.
В противном случае, я рекомендую взглянуть на методику последовательной сериализации. (Кодировка Go Go не самая лучшая.)
... Или мне придется обрабатывать GOB как свою единицу ввода-вывода и понести штраф за кодирование / декодирование?
Просто используйте GOBs. Преждевременная оптимизация - корень всего зла.