Definition
An instance of type BlockCoder<Coder> encodes a source stream as follows:
It divides the stream into equally sized blocks and encodes each block
seperately with an instance of type Coder. If you later want to decode
only parts of the encoded data then you do not have to decode the entire
data but only the appropriate blocks, which is usually much faster.
(The block size can be specified by the user; please note that the
main memory of your computer has to be large enough to hold one block.)
The class BlockCoder has been designed to speed up the seek operations of
the class decoding_ifstream<Coder> (see Section decoding_ifstream).
In order to gain the speed up simply replace the template parameter Coder
in decoding_ifstream by BlockCoder<Coder> (see also the example below).
There is an important precondition for BlockCoder:
In encoding mode the target stream must support seek operations which query the
current position (i.e. seek(0, ios::cur, ios::out)).
In decoding mode the source stream must be capable of random seek operations.
These conditions are surely fullfilled if the respective stream is a file.
Moreover, if BlockCoder is used within a coder pipe the pipe will make sure that
it operates properly. However, this configuration only makes sense if all
coders in the pipe optimize seek operations. Then the whole pipe will offer
fast seek operations.
#include < LEDA/coding/block_coder.h >
Creation
BlockCoder<Coder> | C(streambuf* src_stream = 0, streambuf* tgt_stream = 0, bool own_streams = false, uint32 block_size = DefaultBlockSize) | |
creates an instance C which uses the given source and target streams. If own_streams is set, then C is responsible for the destruction of the streams, otherwise the pointers src_stream and tgt_stream must be valid during the life-time of C. The initial block size is block_size. | ||
BlockCoder<Coder> | C(const char* src_file_name, const char* tgt_file_name, uint32 block_size = DefaultBlockSize) | |
creates an instance C which uses file-streams for input and output. The block size is set to block_size. |
Operations
Standard Operations
void | C.encode() | encodes the source stream and writes the output to the target stream. |
void | C.decode() | decodes the source stream and writes the output to the target stream. |
uint32 | C.encode_memory_chunk(const char* in_buf, uint32 in_len, char* out_buf, uint32 out_len) | |
encodes the memory chunk starting at in_buf with size in_len into the buffer starting at out_buf with size out_len. The function returns actual length of the encoded chunk which may be smaller than out_len. If the output buffer is too small for the encoded data the failure flag will be set (see below). | ||
uint32 | C.decode_memory_chunk(const char* in_buf, uint32 in_len, char* out_buf, uint32 out_len) | |
decodes a memory chunk. The meaning of the parameters and the return value is the same as in the previous function. | ||
streambuf* | C.get_src_stream() | returns the current source stream. |
void | C.set_src_stream(streambuf* src_stream, bool own_stream = false) | |
sets the source stream (cf. constructor). | ||
void | C.set_src_file(const char* file_name) | |
sets a file as source stream. | ||
streambuf* | C.get_tgt_stream() | returns the current target stream. |
void | C.set_tgt_stream(streambuf* tgt_stream, bool own_Stream = false) | |
sets the target stream (cf. constructor). | ||
void | C.set_tgt_file(const char* file_name) | |
sets a file as target stream. | ||
void | C.reset(bool keep_block_size = true) | |
puts C in the same state as the default constructor. If keep_block_size is false, the block size is set to the default value. | ||
bool | C.failed() | returns true if an error occured. |
bool | C.finished() | returns true if the coding is finished. |
string | C.get_description() | provides a description for C. |
Additional Operations
Example
The following example shows how BlockCoder can be used to speed up seek operations. We encode a file of about 3.85 MB, once with A0Coder and once with BlockCoder<A0Coder>. We feed each encoded file into an autodecoding_ifstream and perform random seeks. The file encoded with BlockCoder is slightly longer but seek operations become much faster.
#include <LEDA/coding/compress.h> #include <LEDA/core/random_source.h> #include <LEDA/system/file.h> #include <LEDA/system/timer.h> using namespace LEDA; void test_random_seek(istream& is) { const int buffer_sz = 100; char buffer[buffer_sz]; is.seekg(0, ios::end); streamoff size = (streamoff) is.tellg(); // yields the size of the original file random_source rs; rs.set_seed(0); rs.set_range(0, size - buffer_sz - 1); timer t("seek"); t.start(); for (int i = 0; i < 100; ++i) { is.seekg(rs()); is.read(buffer, buffer_sz); // random seek } t.stop(); } int main() { typedef A0Coder Coder; string in_file = "D:\HTML{BR}{}ctemp\HTML{BR}{}bible.txt"; // 3,85MB string out_file1 = tmp_file_name(), out_file2 = tmp_file_name(); Coder c1(in_file, out_file1); c1.encode(); c1.reset(); cout << "encoded size: " << size_of_file(out_file1) << endl; autodecoding_ifstream is1(out_file1); test_random_seek(is1); is1.close(); // output on my machine: enc. sz: 2201723 / Timer(seek): 51.36 s BlockCoder<Coder> c2(in_file, out_file2); c2.encode(); c2.reset(); cout << "encoded size: " << size_of_file(out_file2) << endl; autodecoding_ifstream is2(out_file2); test_random_seek(is2); is2.close(); // output on my machine: enc. sz: 2207892 / Timer(seek): 1.91 s delete_file(out_file1); delete_file(out_file2); return 0; }