On 2014-02-02 Brandon Fergerson wrote:
> With that being said I've been trying to find out how to write 
> compressed data to a compressed file. My game's map structure is 
> formatted in a way such that a collection of tiles is grouped into a 
> block. So each XZ Block contains a certain amount of tiles. What I
> would like to do is when a player changes tiles of the map the map
> would find the XZ Block that the modified tile is in and rewrite that
> entire compressed block but with the new compressed data.

The new compressed XZ Block might be bigger than the old one because
the new data might be less compressible. Then the new XZ Block cannot
fit in the place of the old one and one has to rewrite the rest of the
file to make space for the new bigger XZ Block. This is slow if the file
is big and it's not really random access in practice.

> Is there any reason a SeekableXZOutputStream was not made or needed?

XZ isn't suitable for random access writing. The data is required to be
in sequential order and decompressible in streamed mode. Good random
access writing would probably allow the data be in non-sequential order
and thus break the streamability requirement.

> So my question is how possible is this and hard would it be? Are
> there indexes of the locations of the XZ Blocks somewhere that would
> have to be updated?

The XZ Index is near the end of the file. It stores the compressed and
uncompressed sizes of the XZ Blocks. But this doesn't help you due to
reasons explained above.

The simplest solution for you could be to write each group of tiles
into a separate compressed file. Then you can overwrite the file when
the tiles in it have been updated. A downside of this is that you may
end up creating even thousands of files and, depending on the file
system, things can slow down.

There are several ways to keep the tiles in a single file. For example,
you could put a fixed-size index to the beginning of the file and the
compressed tile groups after the index. The index would be small enough
to keep in RAM when the game is running. To update a tile group, find a
big enough unused hole (you need a way to track unused space) to store
the new data or if there is no big enough hole, append the data at the
end of the file.

There may be better ways to do it and I wouldn't be surprised if there
were good libraries to do this kind of things (I don't know any but I
haven't searched either). You don't need a full file system, something
relatively simple should be enough.

-- 
Lasse Collin  |  IRC: Larhzu @ IRCnet & Freenode

Reply via email to