// ========== This file is under LGPL, the GNU Lesser General Public Licence // ========== Dialing Lemmatizer (www.aot.ru) // ========== Copyright by Alexey Sokirko #ifndef __index_vector_h_ #define __index_vector_h_ /* CStaticVectorMap is a class for storing and retrieving a vector of T by a key. The key is of DWORD and there should be no holes between two neighbour keys. i.e. for each i key[i]+1 = key[i+1]. */ template class CStaticVectorMap { // the keys, each item points to the beginning of the vector. For example, // "m_Keys[i] = j" means that the vector No i starts from j position. // One "CStaticVectorMap" stores m_Keys.size() vectors. vector< DWORD > m_Keys; // the base of the index vector< T > m_Base; public: typedef typename vector::const_iterator const_iter_t; const_iter_t GetVectorEnd (DWORD VectorNo) const { return ( VectorNo+1 == m_Keys.size() ) ? m_Base.end() : m_Base.begin() + m_Keys[VectorNo + 1]; } const_iter_t GetVectorBegin (DWORD VectorNo) const { assert(VectorNo < m_Keys.size()); return m_Base.begin() + m_Keys[VectorNo]; } DWORD GetVectorLength (DWORD VectorNo) const { const_iter_t begin = GetVectorBegin(VectorNo); const_iter_t end = GetVectorEnd(VectorNo); return end - begin; } DWORD size() const { return m_Keys.size(); } bool empty() const { return m_Keys.empty(); } void Create(vector< vector >& src) { m_Keys.resize( src.size() ); m_Base.clear(); for (DWORD i = 0; i < src.size(); i++) { m_Keys[i] = m_Base.size(); m_Base.insert(m_Base.end(), src[i].begin(), src[i].end()); }; } bool LoadVectorMap(string filename) { FILE* fp; try { fp = fopen(filename.c_str(), "rb"); if (!fp) return false; DWORD Length; fread ((void *)&Length, 1, sizeof(DWORD), fp); assert(Length > 0); ReadVectorInner(fp, m_Keys, Length); fread ((void *)&Length, 1, sizeof(DWORD), fp); ReadVectorInner(fp, m_Base, Length); fclose (fp); } catch(...) { return false; } return true; } bool SaveVectorMap(string filename) { try { FILE* fp = fopen(filename.c_str(), "wb"); if (!fp) return(false); DWORD nCount = m_Keys.size(); fwrite((void *)&nCount, sizeof(DWORD), 1, fp); WriteVectorInner(fp, m_Keys); nCount = m_Base.size(); fwrite ((void *)&nCount, sizeof(DWORD), 1, fp); WriteVectorInner(fp, m_Base); fclose(fp); } catch(...) { return false; } return true; } size_t GetBaseSize() const { return m_Base.size(); }; bool GetKeyByBaseNo(DWORD BaseNo, DWORD& KeyNo, DWORD& DataNo) const { KeyNo = 0; if (BaseNo != 0) { vector::const_iterator it = lower_bound(m_Keys.begin(), m_Keys.end(), BaseNo); if (it == m_Keys.begin()) return false; if (it == m_Keys.end()) return false; if (BaseNo < *it) it--; KeyNo = it - m_Keys.begin(); }; DataNo = BaseNo - m_Keys[KeyNo]; return true; }; }; #endif