Я предлагаю представлять ваши данные в массиве, который отображается на двухмерную плоскость, используя кривую заполнения пространства, такую как кривая Гильберта .
Затем сожмите ее, используя комбинацию кодирование Хаффмана и кодирование длин серий .Это будет особенно эффективно, если ваши данные часто повторяются локально (т. Е. Есть много разделов, которые находятся на одной плитке рядом друг с другом).
Выполните это сжатие в блоках, скажем, 256 плиток.Затем имейте массив смещений, которые указывают, насколько далеко в сжатые данные входят определенные числа байтов.
Например, начало второго байта блока (элемент 256) может быть в позиции 103, а началотретий блок (фрагмент 512) может быть в позиции 192.
Затем, скажем, чтобы получить доступ к 400-му фрагменту, вы можете решить, что это из второго блока, поэтому распакуйте второй блок (в данном случае из байта 103).до байта 191) и отсюда получаем плитку 400 - 256 = 144.Сохраните (кэшируйте) эти распакованные данные на данный момент, вероятно, если вы получаете соседние тайлы, они также будут в этом распакованном блоке.Возможно, в вашем массиве смещений вы должны также указать, какие блоки были недавно кэшированы, и где они находятся в кэше.
Если вы хотите разрешить изменения, вам, вероятно, придется изменить структуру данных с одного большого массива на вектор векторов.Есть индикатор для каждого вектора, является ли он сжатым или нет.При выполнении модификаций распаковывайте блоки и изменяйте их, а затем повторно сжимайте блоки, которые были изменены в последний раз, когда память заканчивается.
Или вы можете просто вывести всю структуру в файл и памятькарта файл.Это намного проще, но может быть медленнее в зависимости от сжимаемости ваших данных и ваших схем доступа из-за дополнительных операций ввода-вывода.