Share Library (C++)
File detail
Source code
/**
* @file test2_wordcount.cpp
* @brief Share library - test2 (WordCount)
* @author Kamil Dudka, xdudka00@gmail.com
* @date 2007-05-15
*/
#include "sharelib.h"
#include <iostream>
#include <fstream>
#include <sstream>
//class CreateSegmentRAII {
// static const size_t segmentSize = 160*1024*1024;
// public:
// CreateSegmentRAII (const char *name)
// {
// Share::ShareManager *manager = Share::ShareManager::instance();
// manager-> createSegment (name, segmentSize);
// }
//
// ~CreateSegmentRAII()
// {
// Share::ShareManager *manager = Share::ShareManager::instance();
// manager-> detachSegment();
// }
//};
/**
* Attached shared segment
* RAII (Resource Acquisition Is Initialization) object
*/
class AttachSegmentRAII {
public:
AttachSegmentRAII (const char *name)
{
// attach shared segment
Share::ShareManager *manager = Share::ShareManager::instance();
manager-> attachSegment (name);
}
~AttachSegmentRAII()
{
// detach shared segment
Share::ShareManager *manager = Share::ShareManager::instance();
manager-> detachSegment();
}
};
/**
* Word-counting shared object's class
*/
class WordCount: public Share::SharedObject {
// hash table size
static const size_t htSize = 16384;
public:
WordCount(): hashTable_(htSize) { }
// add word-count statistics from file fileName
void parse (const char *fileName);
friend std::ostream& operator<< (std::ostream &, WordCount &);
private:
typedef Share::String <Share::Allocator <char> > TString;
typedef Share::Allocator <Share::Pair <TString, int> > TAllocator;
typedef Share::Map<TString, int, TAllocator> THashTable;
THashTable hashTable_;
};
/**
* Print word-count statistics to output stream
*/
std::ostream& operator<< (std::ostream &, WordCount &);
/**
* Pointer to shared object
*/
typedef Share::RelocPtr<WordCount> PWordCount;
// argc==1: Print usage
// argc==2: Create shared wordcount object
// argc==3: Print shared wordcount statistics
// argc==4: Parse file given as 3rd argument and add statistics to shared wordcount object
int main (int argc, char *argv[])
{
try {
switch (argc) {
default:
std::cout <<
"Usage:\n"
" test2_wordcount SEGMENT\n"
" test2_wordcount SEGMENT POINTER\n"
" test2_wordcount SEGMENT POINTER FILE_TO_PARSE\n";
return 1;
case 2: {
// Attach to existing shared segment
const char *name = argv[1];
AttachSegmentRAII segmentRAII (name);
// Create new WordCount object inside shared segment
PWordCount wc = new WordCount;
std::cout << "Created WordCount shared object:" << std::endl;
std::cout << " Shared segment name: " << name << std::endl;
std::cout << " Relative object address: " << wc.toRel() << std::endl;
return 0;
}
case 3:
case 4:
break;
}
// Read relative address of WordCount object from command-line
PWordCount::relative_pointer relPtr;
std::istringstream stream (argv[2]);
if (! (stream >> relPtr))
throw Share::ShareException ("Invalid object address");
// Attach to already existing shared segment
AttachSegmentRAII segmentRAII (argv[1]);
PWordCount wc = PWordCount::fromRel (relPtr);
if (argc==3)
// Print statistics
std::cout << *wc;
else if (argc==4)
// Parse file
wc-> parse (argv[3]);
}
catch (Share::ShareException e) {
// error handling
std::cerr << "test2_wordcount: " << e.message() << std::endl;
}
}
void WordCount::parse (const char *fileName)
{
// open input file (RAII object)
class OpenedFileRAII {
std::ifstream fin_;
public:
OpenedFileRAII (const char *fileName): fin_ (fileName) { }
~OpenedFileRAII() { fin_.close(); }
operator std::ifstream &() { return fin_; }
operator bool() { return fin_; }
} fin (fileName);
if (!fin) {
// error occured while opening input file
std::ostringstream stream;
stream << "Unable to read file " << fileName;
throw Share::ShareException (stream.str().c_str());
}
// parse file word after word
for (std::string word; static_cast<std::ifstream &>(fin) >> word; ) {
TString str (word.c_str());
hashTable_ [str] ++;
}
}
std::ostream& operator<< (std::ostream &out, WordCount &wc)
{
// print word-count statistics using iterator
WordCount::THashTable::const_iterator current;
for (current = wc.hashTable_.begin(); current != wc.hashTable_.end(); current++)
out << "\"" << current->first.c_str() << "\": " << current->second << std::endl;
return out;
}