/* * Copyright (c) 2020 Red Hat, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. * * $Id: //eng/uds-releases/jasper/src/uds/cachedChapterIndex.c#3 $ */ #include "cachedChapterIndex.h" #include "memoryAlloc.h" /**********************************************************************/ int initializeCachedChapterIndex(CachedChapterIndex *chapter, const Geometry *geometry) { chapter->virtualChapter = UINT64_MAX; chapter->indexPagesCount = geometry->indexPagesPerChapter; int result = ALLOCATE(chapter->indexPagesCount, DeltaIndexPage, __func__, &chapter->indexPages); if (result != UDS_SUCCESS) { return result; } result = ALLOCATE(chapter->indexPagesCount, struct volume_page, "sparse index VolumePages", &chapter->volumePages); if (result != UDS_SUCCESS) { return result; } unsigned int i; for (i = 0; i < chapter->indexPagesCount; i++) { result = initializeVolumePage(geometry, &chapter->volumePages[i]); if (result != UDS_SUCCESS) { return result; } } return UDS_SUCCESS; } /**********************************************************************/ void destroyCachedChapterIndex(CachedChapterIndex *chapter) { if (chapter->volumePages != NULL) { unsigned int i; for (i = 0; i < chapter->indexPagesCount; i++) { destroyVolumePage(&chapter->volumePages[i]); } } FREE(chapter->indexPages); FREE(chapter->volumePages); } /**********************************************************************/ int cacheChapterIndex(CachedChapterIndex *chapter, uint64_t virtualChapter, const Volume *volume) { // Mark the cached chapter as unused in case the update fails midway. chapter->virtualChapter = UINT64_MAX; // Read all the page data and initialize the entire DeltaIndexPage array. // (It's not safe for the zone threads to do it lazily--they'll race.) int result = readChapterIndexFromVolume(volume, virtualChapter, chapter->volumePages, chapter->indexPages); if (result != UDS_SUCCESS) { return result; } // Reset all chapter counter values to zero. chapter->counters.searchHits = 0; chapter->counters.searchMisses = 0; chapter->counters.consecutiveMisses = 0; // Mark the entry as valid--it's now in the cache. chapter->virtualChapter = virtualChapter; chapter->skipSearch = false; return UDS_SUCCESS; } /**********************************************************************/ int searchCachedChapterIndex(CachedChapterIndex *chapter, const Geometry *geometry, const IndexPageMap *indexPageMap, const UdsChunkName *name, int *recordPagePtr) { // Find the indexPageNumber in the chapter that would have the chunk name. unsigned int physicalChapter = mapToPhysicalChapter(geometry, chapter->virtualChapter); unsigned int indexPageNumber; int result = findIndexPageNumber(indexPageMap, name, physicalChapter, &indexPageNumber); if (result != UDS_SUCCESS) { return result; } return searchChapterIndexPage(&chapter->indexPages[indexPageNumber], geometry, name, recordPagePtr); }