XCube Stream Reader SDK
|
00001 00008 #ifndef __CINDEXER_H__ 00009 #define __CINDEXER_H__ 00010 00011 #include <map> 00012 #include <cassert> 00013 #include <iostream> 00014 #include <cstring> 00015 00016 #include "xcTypes.h" 00017 00018 /* 00019 ** Debugging macros 00020 */ 00021 00022 /* Define as 1 to enable debug facilities */ 00023 #define DEBUG_ENABLED 0 00024 #define DEBUG_PRINT_ENABLED 0 00025 00026 #if !defined(NDEBUG) && DEBUG_CHECK_ENABLED 00027 #define DEBUG_CHECK(cond) \ 00028 assert(cond) 00029 00030 #else 00031 #define DEBUG_CHECK(cond) 00032 #endif 00033 00034 #if !defined(NDEBUG) && DEBUG_PRINT_ENABLED 00035 #define DEBUG_PRINT(str) \ 00036 std::cerr << "!!!!ERROR encountered at " \ 00037 << __FILE__ << ":" << __LINE__ \ 00038 << " : " << (str) << std::endl; 00039 #else 00040 #define DEBUG_PRINT(str) 00041 #endif 00042 00043 namespace x3c { 00044 namespace indexer { 00045 00046 const UINT32 THIRTYTWO_MB = 32*1024*1024; 00047 00051 #if !defined(NDEBUG) && DEBUG_ENABLED 00052 #define CHECK_HEADER_LENGTH \ 00053 do { \ 00054 assert(0x2000 == sizeof(IndexHeader)); \ 00055 } while (0); 00056 00057 #define CHECK_TRAILER_LENGTH \ 00058 do { \ 00059 assert(0x2000 == sizeof(IndexHeader)); \ 00060 } while (0); 00061 #else 00062 #define CHECK_HEADER_LENGTH 00063 #define CHECK_TRAILER_LENGTH 00064 #endif /* NDEBUG */ 00065 00073 template<class IndexPolicy> 00074 class CIndexer 00075 { 00076 public: 00077 00078 //================================================================== 00079 // typedefs 00080 // 00081 typedef std::map<std::string, IndexPolicy*> IndexerMap; 00082 typedef typename std::map<std::string, IndexPolicy*>::iterator IndexerIter; 00083 typedef typename std::map<std::string, IndexPolicy*>::const_iterator ConstIndexerIter; 00084 00088 explicit CIndexer(UINT32 numFiles, 00089 UINT32 reservedMem = THIRTYTWO_MB); 00090 00094 ~CIndexer(); 00095 00104 IndexPolicy* getIndexer(std::string const& filename); 00105 00118 std::string getOffsetFromTime(UINT64 ts, UINT64 *offset) const; 00119 00132 std::string getOffsetFromTime(struct timespec ts, UINT64 *offset) const; 00133 00138 void closeIndexFiles(); 00139 00143 UINT32 numFiles() const; 00144 00148 void numFiles(UINT32 nFiles); 00149 00155 void timeZone(INT32 gmt_offset); 00156 00160 INT32 timeZone() const; 00161 00162 private: 00166 CIndexer& operator=(CIndexer<IndexPolicy> const&); 00167 00171 CIndexer(CIndexer<IndexPolicy> const&); 00172 00174 UINT32 mNumFiles; 00175 00179 UINT32 mReservedMem; 00180 00182 INT32 mGmtOffset; 00183 00184 IndexerMap indexers; 00185 }; 00186 00187 /* 00188 ** Inline member function implementations 00189 */ 00190 00191 template<class IndexPolicy> inline 00192 void CIndexer<IndexPolicy>::timeZone(INT32 gmtOffset) 00193 { 00195 mGmtOffset = gmtOffset; 00196 } 00197 00198 template<class IndexPolicy> inline 00199 INT32 CIndexer<IndexPolicy>::timeZone() const 00200 { 00201 return mGmtOffset; 00202 } 00203 00204 template<class IndexPolicy> inline 00205 UINT32 CIndexer<IndexPolicy>::numFiles() const 00206 { 00207 return mNumFiles; 00208 } 00209 00210 template<class IndexPolicy> inline 00211 void CIndexer<IndexPolicy>::numFiles(UINT32 nFiles) 00212 { 00213 mNumFiles = nFiles; 00214 } 00215 00216 00217 00218 //====================================================================== 00219 // CIndexer class implementation 00220 // 00221 template<class IndexPolicy> 00222 CIndexer<IndexPolicy>::CIndexer(UINT32 numFiles, 00223 UINT32 reserve /* = THIRTYTWO_MB*/) 00224 : mNumFiles(numFiles), mReservedMem(reserve), mGmtOffset(0), 00225 indexers() 00226 { 00227 CHECK_HEADER_LENGTH; 00228 CHECK_TRAILER_LENGTH; 00229 } 00230 00231 template<class IndexPolicy> 00232 CIndexer<IndexPolicy>::~CIndexer() 00233 { 00234 IndexerIter iter = indexers.begin(); 00235 IndexerIter last = indexers.end(); 00236 while ( iter != last ) { 00237 IndexPolicy* p = (*iter).second; 00238 delete p; 00239 ++iter; 00240 } 00241 00242 indexers.clear(); 00243 } 00244 00245 template<class IndexPolicy> 00246 IndexPolicy* CIndexer<IndexPolicy>::getIndexer(std::string const& filename) 00247 { 00248 IndexPolicy *pIndexer = 0; 00249 IndexerIter i; 00250 00251 if ( indexers.end() != (i = indexers.find(filename)) ) { 00252 pIndexer = i->second; 00253 } else { 00254 pIndexer = new IndexPolicy(*this, mReservedMem); 00255 if (0 != pIndexer) { 00256 if (pIndexer->create(filename)) { 00257 /* Store a pointer to the reader */ 00258 indexers[filename] = pIndexer; 00259 } else { 00260 delete pIndexer; 00261 pIndexer = NULL; 00262 00263 DEBUG_PRINT("CIndexer::getIndexer: Failed to " 00264 "initialize Indexer"); 00265 } 00266 } else { 00267 DEBUG_PRINT("CIndexer::getIndexer: Out of Memory"); 00268 } 00269 } 00270 00271 DEBUG_CHECK(0 != pIndexer); 00272 00273 return pIndexer; 00274 } 00275 00276 template<class IndexPolicy> 00277 void CIndexer<IndexPolicy>::closeIndexFiles() 00278 { 00279 IndexerIter iter = indexers.begin(); 00280 IndexerIter last = indexers.end(); 00281 while ( iter != last ) { 00282 IndexPolicy* p = (*iter).second; 00283 p->close(); 00284 ++iter; 00285 } 00286 } 00287 00288 template<class IndexPolicy> std::string 00289 CIndexer<IndexPolicy>::getOffsetFromTime(UINT64 ts, 00290 UINT64 *offset) const 00291 { 00292 UINT64 filePos; 00293 std::string fname; 00294 fname.clear(); 00295 00296 assert(NULL != offset); 00297 00298 *offset = -1; 00299 00300 ConstIndexerIter iter = indexers.begin(); 00301 ConstIndexerIter last = indexers.end(); 00302 while ( iter != last ) { 00303 IndexPolicy* p = (*iter).second; 00304 00305 if (p->mHeader.start_time < ts && p->mHeader.end_time > ts) { 00306 // if ( -1 != (filePos = p->getFilePosByTime(ts)) ) 00307 int nRetVal = p->getFilePosByTime(ts, filePos); 00308 if (0 == nRetVal) 00309 { 00310 *offset = filePos; 00311 fname = iter->first; 00312 break; 00313 } 00314 } 00315 ++iter; 00316 } 00317 00318 return fname; 00319 } 00320 00321 template<class IndexPolicy> 00322 std::string CIndexer<IndexPolicy>::getOffsetFromTime(struct timespec ts, 00323 UINT64 *offset) const 00324 { 00325 const UINT64 timestamp(ts.tv_sec << 32 | ts.tv_nsec); 00326 return getOffsetFromTime((UINT64)timestamp, offset); 00327 } 00328 00329 } /* namespace indexer */ 00330 } /* namespace x3c */ 00331 00332 #endif /* __CINDEXER_H__ */