commitid_t IndexBarrelKeeper::refreshDataForUpdate() { BarrelsInfoPtr pBarrelsInfo(new BarrelsInfo()); pBarrelsInfo->read(m_pFileSys); commitid_t latestCommit = pBarrelsInfo->getCommitId(); commitid_t prevCommit = INVALID_COMMIT; IndexBarrelPtr pLastBarrel; { ScopedRWLock lock(m_lock, false); if (!m_commitMap.empty()) { pLastBarrel = m_commitMap.rbegin()->second; prevCommit = pLastBarrel->getBarrelsInfo()->getCommitId(); } } if (latestCommit == prevCommit) { return prevCommit; } if (prevCommit == INVALID_COMMIT) { return loadOnDiskDataForUpdate(pBarrelsInfo); } IndexBarrelReaderPtr pReader; DeletedDocumentFilterPtr pDocFilter(pLastBarrel->getDeletedDocFilter()->clone()); pDocFilter->reopen(pBarrelsInfo); PrimaryKeyIndexPtr pPrimKey; if (m_pOnDiskPrimKeyIndex) { pPrimKey.reset(m_pOnDiskPrimKeyIndex->clone()); pPrimKey->reopen(pBarrelsInfo); } IndexBarrelReaderPtr pLastReader; IndexBarrelPtr pBarrel(new IndexBarrel(pBarrelsInfo, pReader, pDocFilter)); pBarrel->setEncoding(m_sEncoding); { ScopedRWLock lock(m_lock, true); bool bInserted = doInsertCommit(latestCommit, pBarrel); if (bInserted) { m_pOnDiskDocFilter = pDocFilter; m_pOnDiskPrimKeyIndex = pPrimKey; return latestCommit; } return prevCommit; } }
commitid_t IndexBarrelKeeper::refreshDataForRead() { BarrelsInfoPtr pBarrelsInfo(new BarrelsInfo()); pBarrelsInfo->read(m_pFileSys); commitid_t latestCommit = pBarrelsInfo->getCommitId(); commitid_t prevCommit = INVALID_COMMIT; IndexBarrelPtr pLastBarrel; { ScopedRWLock lock(m_lock, false); if (!m_commitMap.empty()) { pLastBarrel = m_commitMap.rbegin()->second; prevCommit = pLastBarrel->getBarrelsInfo()->getCommitId(); } } if (latestCommit == prevCommit) { return prevCommit; } if (prevCommit == INVALID_COMMIT) { return createOnDiskBarrelReader(pBarrelsInfo); } FX_LOG(INFO, "Begin reopen index database, commitId: [%d]", latestCommit); IndexBarrelReaderPtr pReader; DeletedDocumentFilterPtr pDocFilter(pLastBarrel->getDeletedDocFilter()->clone()); pDocFilter->reopen(pBarrelsInfo); PrimaryKeyIndexPtr pPrimKey; if (m_pOnDiskPrimKeyIndex) { pPrimKey.reset(m_pOnDiskPrimKeyIndex->clone()); pPrimKey->reopen(pBarrelsInfo); } BarrelsInfoPtr pLastBarrelsInfo = pLastBarrel->getBarrelsInfo(); IndexBarrelReaderPtr pLastReader = pLastBarrel->getReader(); size_t bc = pBarrelsInfo->getBarrelCount(); if (bc == 1) { if (pLastBarrelsInfo->getBarrelCount() > 1 || pBarrelsInfo->getCommitId() - pLastBarrelsInfo->getCommitId() > 1) { const BarrelInfo& lastBarrelInfo = pBarrelsInfo->getLastBarrel(); const BitVector* pBitVector = pDocFilter->getDocFilter(lastBarrelInfo.getBaseDocId()); SingleIndexBarrelReader* pSingleReader = new SingleIndexBarrelReader( m_pFileSys, m_pDocSchema, m_pComponentBuilder); pReader.reset(pSingleReader); pSingleReader->open(&lastBarrelInfo, pBitVector); } else { const BarrelInfo& lastBarrelInfo = pBarrelsInfo->getLastBarrel(); const BitVector* pBitVector = pDocFilter->getDocFilter(lastBarrelInfo.getBaseDocId()); pReader.reset(pLastReader->clone()); SingleIndexBarrelReaderPtr pSingleReader = std::dynamic_pointer_cast<SingleIndexBarrelReader>(pReader); FIRTEX_ASSERT2(pSingleReader); pSingleReader->reopen(&lastBarrelInfo, pBitVector); } } else if (bc > 1) { if (pLastBarrelsInfo->getBarrelCount() > 1) { pReader.reset(pLastReader->clone()); MultiIndexBarrelReaderPtr pMultiReader = std::dynamic_pointer_cast<MultiIndexBarrelReader>(pReader); FIRTEX_ASSERT2(pMultiReader); pMultiReader->reopen(pBarrelsInfo, pDocFilter); } else { //TODO: optimize? MultiIndexBarrelReader* pMultiReader = new MultiIndexBarrelReader( m_pFileSys, m_pDocSchema, m_pComponentBuilder); pReader.reset(pMultiReader); pMultiReader->open(pBarrelsInfo, pDocFilter); } } FX_LOG(INFO, "End reopen index database."); IndexBarrelPtr pBarrel(new IndexBarrel(pBarrelsInfo, pReader, pDocFilter)); pBarrel->setEncoding(m_sEncoding); { ScopedRWLock lock(m_lock, true); bool bInserted = doInsertCommit(latestCommit, pBarrel); if (bInserted) { m_pOnDiskDocFilter = pDocFilter; m_pOnDiskPrimKeyIndex = pPrimKey; return latestCommit; } return prevCommit; } }
void Index::open(FileSystemPtr& pFileSys, AccessMode am, const DocumentSchema* pDocSchema) { FIRTEX_ASSERT2(m_pFileSys.isNull()); m_pFileSys = pFileSys; m_accessMode = am; BarrelsInfoPtr pBarrelsInfo(new BarrelsInfo()); pBarrelsInfo->read(pFileSys);//read barrels Info if (am == WRITE) { if (!pDocSchema) { FIRTEX_THROW(InvalidConfigException, "Schema is empty in write mode."); } m_pDocSchema = new DocumentSchema(*pDocSchema); writeSchema(m_pDocSchema, pFileSys); pBarrelsInfo->remove(m_pFileSys); m_pComponentBuilder = new ComponentBuilder(); m_pComponentBuilder->init(m_pDocSchema); initAnalyzerMapper(); m_pIndexBarrelKeeper = new IndexBarrelKeeper(m_pFileSys, m_pDocSchema.get(), m_pComponentBuilder.get(), m_pAnalyzerMapper.get()); m_pIndexBarrelKeeper->init(pBarrelsInfo, IndexBarrelKeeper::WRITE); openWriter(); } else // READ, APPEND or RDWR mode { if (pBarrelsInfo->getIndexVersion() != FX_INDEX_VERSION) { FIRTEX_THROW(VersionException, "Incompatible index version."); } if (pBarrelsInfo->getBarrelCount() > 0) { DocumentSchemaPtr pSchemaExist = readSchema(m_pFileSys); if (pSchemaExist.isNull()) { FIRTEX_THROW(IndexCollapseException, "Read schema FAILED."); } if (pDocSchema && !pSchemaExist->isEqual(*pDocSchema)) { FIRTEX_THROW(IllegalArgumentException, "The given document schema is not equal to the existing schema."); } m_pDocSchema = pSchemaExist; } else { if (!pDocSchema) { FIRTEX_THROW(IllegalArgumentException, "No document schema is specified."); } m_pDocSchema = new DocumentSchema(*pDocSchema); } m_pComponentBuilder = new ComponentBuilder(); m_pComponentBuilder->init(m_pDocSchema); initAnalyzerMapper(); m_pIndexBarrelKeeper = new IndexBarrelKeeper(m_pFileSys, m_pDocSchema.get(), m_pComponentBuilder.get(), m_pAnalyzerMapper.get()); if (am == READ || am == RDWR) { m_pIndexBarrelKeeper->init(pBarrelsInfo, (am == READ) ? IndexBarrelKeeper::READ : IndexBarrelKeeper::RDWR); openReader(); if (am == RDWR) { openWriter(); } } else if (am == APPEND) { m_pIndexBarrelKeeper->init(pBarrelsInfo, IndexBarrelKeeper::WRITE); openWriter(); } } }