next up previous contents index
Next: Memory Streambuffer ( memory_streambuf Up: Lossless Compression Previous: Automatic Decoder ( AutoDecoder   Contents   Index


Block Coder ( BlockCoder )

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

uint32 C.get_block_size() returns the current block size.

void C.set_block_size(uint32 block_size)
    sets the block size.

Coder* C.get_coder() returns the instance of Coder which is actually used for encoding and decoding.

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;
}


next up previous contents index
Next: Memory Streambuffer ( memory_streambuf Up: Lossless Compression Previous: Automatic Decoder ( AutoDecoder   Contents   Index