Я полагаю, что вам нужен массив , элементы которого хранятся не ванильно, а сжато , чтобы минимизировать использование памяти.
Что касается сжатия, у вас нетИсключительное понимание структуры ваших данных, так что вы в порядке с некоторой стандартной энтропийной кодировкой .В идеале, хотелось бы запустить GZIP для всего массива и покончить с ним, но это потеряло бы доступ O (1), что крайне важно для вас.
A решение заключается виспользуйте кодирование Хаффмана вместе с индексной таблицей .
Кодирование Хаффмана работает путем замены каждого входного символа (например, байта ASCII) другим символом переменная длина бита, в зависимости от частоты появления во всем потоке.Например, символ E
появляется очень часто, поэтому он получает короткую битовую последовательность, в то время как 'W' редко и получает длинную битовую последовательность.
E -> 0b10
W -> 0b11110
Теперь сожмите весь массив с помощью этогометод.К сожалению, поскольку выходные символы имеют переменную длину, вы больше не можете индексировать свои данные, как раньше: номер элемента 15 больше не равен stream[15*sizeof(item)]
.
К счастью, эту проблему можно решить с помощью дополнительного индексная таблица index
, в которой хранится начало каждого элемента в сжатом потоке.Другими словами, сжатые данные для элемента 15 можно найти на stream[index[15]]
;В индексной таблице накапливаются переменные выходные значения.
Итак, чтобы получить элемент 15, вы просто начинаете распаковывать байты с stream[index[15]]
.Это работает, потому что кодирование Хаффмана не делает ничего необычного для вывода, оно просто объединяет новые кодовые слова, и вы можете начать декодирование внутри потока без необходимости декодировать все предыдущие элементы.
Конечно,индексная таблица добавляет некоторые накладные расходы ;Вы можете настроить гранулярность так, чтобы compressed data + index table
все еще был меньше, чем original data
.