// -*- c++ -*- // In-memory corpus track // (c) 2006-2012 Ulrich Germann. #ifndef __ug_im_ttrack #define __ug_im_ttrack #include #include #include #include #include #include "tpt_typedefs.h" #include "tpt_tokenindex.h" #include "ug_ttrack_base.h" #include "tpt_tokenindex.h" // #include "ug_vocab.h" // define the corpus buffer size (in sentences) and the // for adding additional sentences: #define IMTTRACK_INCREMENT_SIZE 100000 #define IMTSA_INCREMENT_SIZE 1000000 namespace ugdiss { using namespace std; using namespace boost; namespace bio=boost::iostreams; template class imTSA; template class imTtrack; template typename boost::shared_ptr > append(typename boost::shared_ptr > const & crp, vector const & snt); template class imTtrack : public Ttrack { private: size_t numToks; boost::shared_ptr > > myData; // pointer to corpus data friend class imTSA; friend typename boost::shared_ptr > append(typename boost::shared_ptr > const & crp, vector const & snt); public: imTtrack(boost::shared_ptr > > const& d); imTtrack(istream& in, TokenIndex const& V, ostream* log); imTtrack(size_t reserve = 0); // imTtrack(istream& in, Vocab& V); /** return pointer to beginning of sentence */ Token const* sntStart(size_t sid) const; /** return pointer to beginning of sentence */ Token const* sntEnd(size_t sid) const; size_t size() const; size_t numTokens() const; id_type findSid(Token const* t) const; }; template Token const* imTtrack:: sntStart(size_t sid) const // return pointer to beginning of sentence { assert(sid < size()); if ((*myData)[sid].size() == 0) return NULL; return &((*myData)[sid].front()); } template Token const* imTtrack:: sntEnd(size_t sid) const // return pointer to end of sentence { assert(sid < size()); if ((*myData)[sid].size() == 0) return NULL; return &(*myData)[sid].back()+1; } template size_t imTtrack:: size() const // return size of corpus (in number of sentences) { // we assume that myIndex has pointers to both the beginning of the // first sentence and the end point of the last, so there's one more // offset in the myIndex than there are sentences return myData->size(); } template size_t imTtrack:: numTokens() const // return size of corpus (in number of words) { return numToks; } template imTtrack:: imTtrack(istream& in, TokenIndex const& V, ostream* log = NULL) { myData.reset(new vector >()); numToks = 0; string line,w; size_t linectr=0; boost::unordered_map H; for (id_type i = 0; i < V.knownVocabSize(); ++i) H[V[i]] = i; while (getline(in,line)) { myData->push_back(vector()); if (log && ++linectr%1000000==0) *log << linectr/1000000 << "M lines of input processed" << endl; istringstream buf(line); while (buf>>w) myData->back().push_back(Token(H[w])); myData->back().resize(myData.back().size()); numToks += myData->back().size(); } } template imTtrack:: imTtrack(size_t reserve) { myData.reset(new vector >()); if (reserve) myData->reserve(reserve); } template imTtrack:: imTtrack(boost::shared_ptr > > const& d) { myData = d; numToks = 0; BOOST_FOREACH(vector const& v, *d) numToks += v.size(); } template id_type imTtrack:: findSid(Token const* t) const { id_type i; for (i = 0; i < myData->size(); ++i) { vector const& v = (*myData)[i]; if (v.size() == 0) continue; if (&v.front() <= t && &v.back() >= t) break; } return i; } /// add a sentence to the database template shared_ptr > append(shared_ptr > const& crp, vector const & snt) { shared_ptr > ret; if (crp == NULL) { ret.reset(new imTtrack()); ret->myData->reserve(IMTTRACK_INCREMENT_SIZE); } else if (crp->myData->capacity() == crp->size()) { ret.reset(new imTtrack()); ret->myData->reserve(crp->size() + IMTTRACK_INCREMENT_SIZE); copy(crp->myData->begin(),crp->myData->end(),ret->myData->begin()); } else ret = crp; ret->myData->push_back(snt); return ret; } } #endif