Česky
Kamil Dudka

Share Library (C++)

File detail

Name:Downloadtest2_wordcount.cpp [Download]
Location: sharelib > src > test2
Size:4.6 KB
Last modification:2007-08-27 01:16

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