The following example shows how to perform random read accesses on a
compressed datafile.
#include <LEDA/coding/compress.h> // includes all compression classes
#include <LEDA/core/random.h> // for random
access ...
using namespace leda;
using std::cout;
using std::endl;
using std::ostream;
using std::istream;
string db_file_name = "database";
const int db_sz = 1000;
const int record_sz = 20;
typedef BlockCoder<PPMIICoder> Coder;
// Note: random access is also possible without BlockCoder but much slower!
/*
The code for generating and accessing the database uses
standard C++ streams.
It does not even know that the data is actually compressed
during writing and
decompressed during reading!
*/
void generate_database(std::ostream& db)
{
string fill; while (fill.length() <= record_sz) fill
+= " ";
// used to enlarge the records to
the desired length
for (int i = 0; i < db_sz; ++i) {
// generate record
string record = string("record #%d",
i);
record += fill(1, record_sz - record.length());
// write record into the database
db << record;
}
}
string retrieve_record(std::istream& db, int record_num)
{
// jump to the correct position in the stream
int pos = record_num * record_sz;
// Note: pos is the position in the
uncompressed data!
db.seekg(pos);
// read the record
char buffer[record_sz+1];
db.read(buffer, record_sz);
// add a terminating zero and return it
buffer[record_sz] = 0;
return string(buffer);
}
int main()
{
// build the database
{
encoding_ofstream<Coder> db(db_file_name);
generate_database(db);
db.close();
if (db.fail()) cout << "Error
writing " << db_file_name << endl;
}
// access the database and retrieve some records
{
autodecoding_ifstream db(db_file_name);
random_source rand(0, db_sz);
for (int i = 0; i < 30; ++i) {
int record_num
= rand();
cout << record_num << ": " << retrieve_record(db,
record_num) << endl;
}
}
return 0;
} |