|
Packit Service |
310c69 |
/*
|
|
Packit Service |
310c69 |
* Copyright (c) 2020 Red Hat, Inc.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* This program is free software; you can redistribute it and/or
|
|
Packit Service |
310c69 |
* modify it under the terms of the GNU General Public License
|
|
Packit Service |
310c69 |
* as published by the Free Software Foundation; either version 2
|
|
Packit Service |
310c69 |
* of the License, or (at your option) any later version.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* This program is distributed in the hope that it will be useful,
|
|
Packit Service |
310c69 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
310c69 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit Service |
310c69 |
* GNU General Public License for more details.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* You should have received a copy of the GNU General Public License
|
|
Packit Service |
310c69 |
* along with this program; if not, write to the Free Software
|
|
Packit Service |
310c69 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
Packit Service |
310c69 |
* 02110-1301, USA.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* $Id: //eng/uds-releases/jasper/src/uds/indexZone.c#4 $
|
|
Packit Service |
310c69 |
*/
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
#include "indexZone.h"
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
#include "errors.h"
|
|
Packit Service |
310c69 |
#include "index.h"
|
|
Packit Service |
310c69 |
#include "indexCheckpoint.h"
|
|
Packit Service |
310c69 |
#include "indexRouter.h"
|
|
Packit Service |
310c69 |
#include "logger.h"
|
|
Packit Service |
310c69 |
#include "memoryAlloc.h"
|
|
Packit Service |
310c69 |
#include "permassert.h"
|
|
Packit Service |
310c69 |
#include "request.h"
|
|
Packit Service |
310c69 |
#include "sparseCache.h"
|
|
Packit Service |
310c69 |
#include "uds.h"
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
int makeIndexZone(struct index *index, unsigned int zoneNumber)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
IndexZone *zone;
|
|
Packit Service |
310c69 |
int result = ALLOCATE(1, IndexZone, "index zone", &zone);
|
|
Packit Service |
310c69 |
if (result != UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
return result;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
result = makeOpenChapter(index->volume->geometry, index->zoneCount,
|
|
Packit Service |
310c69 |
&zone->openChapter);
|
|
Packit Service |
310c69 |
if (result != UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
freeIndexZone(zone);
|
|
Packit Service |
310c69 |
return result;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
result = makeOpenChapter(index->volume->geometry, index->zoneCount,
|
|
Packit Service |
310c69 |
&zone->writingChapter);
|
|
Packit Service |
310c69 |
if (result != UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
freeIndexZone(zone);
|
|
Packit Service |
310c69 |
return result;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
zone->index = index;
|
|
Packit Service |
310c69 |
zone->id = zoneNumber;
|
|
Packit Service |
310c69 |
index->zones[zoneNumber] = zone;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
return UDS_SUCCESS;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
void freeIndexZone(IndexZone *zone)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
if (zone == NULL) {
|
|
Packit Service |
310c69 |
return;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
freeOpenChapter(zone->openChapter);
|
|
Packit Service |
310c69 |
freeOpenChapter(zone->writingChapter);
|
|
Packit Service |
310c69 |
FREE(zone);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
bool isZoneChapterSparse(const IndexZone *zone,
|
|
Packit Service |
310c69 |
uint64_t virtualChapter)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
return isChapterSparse(zone->index->volume->geometry,
|
|
Packit Service |
310c69 |
zone->oldestVirtualChapter,
|
|
Packit Service |
310c69 |
zone->newestVirtualChapter,
|
|
Packit Service |
310c69 |
virtualChapter);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
void setActiveChapters(IndexZone *zone)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
zone->oldestVirtualChapter = zone->index->oldestVirtualChapter;
|
|
Packit Service |
310c69 |
zone->newestVirtualChapter = zone->index->newestVirtualChapter;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Swap the open and writing chapters after blocking until there are no active
|
|
Packit Service |
310c69 |
* chapter writers on the index.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param zone The zone swapping chapters
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @return UDS_SUCCESS or a return code
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static int swapOpenChapter(IndexZone *zone)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
// Wait for any currently writing chapter to complete
|
|
Packit Service |
310c69 |
int result = finishPreviousChapter(zone->index->chapterWriter,
|
|
Packit Service |
310c69 |
zone->newestVirtualChapter);
|
|
Packit Service |
310c69 |
if (result != UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
return result;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
// Swap the writing and open chapters
|
|
Packit Service |
310c69 |
OpenChapterZone *tempChapter = zone->openChapter;
|
|
Packit Service |
310c69 |
zone->openChapter = zone->writingChapter;
|
|
Packit Service |
310c69 |
zone->writingChapter = tempChapter;
|
|
Packit Service |
310c69 |
return UDS_SUCCESS;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Advance to a new open chapter, and forget the oldest chapter in the
|
|
Packit Service |
310c69 |
* index if necessary.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param zone The zone containing the chapter to reap
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @return UDS_SUCCESS or an error code
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static int reapOldestChapter(IndexZone *zone)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
Index *index = zone->index;
|
|
Packit Service |
310c69 |
unsigned int chaptersPerVolume = index->volume->geometry->chaptersPerVolume;
|
|
Packit Service |
310c69 |
int result
|
|
Packit Service |
310c69 |
= ASSERT(((zone->newestVirtualChapter - zone->oldestVirtualChapter)
|
|
Packit Service |
310c69 |
<= chaptersPerVolume),
|
|
Packit Service |
310c69 |
"newest (%llu) and oldest (%llu) virtual chapters "
|
|
Packit Service |
310c69 |
"less than or equal to chapters per volume (%u)",
|
|
Packit Service |
310c69 |
zone->newestVirtualChapter, zone->oldestVirtualChapter,
|
|
Packit Service |
310c69 |
chaptersPerVolume);
|
|
Packit Service |
310c69 |
if (result != UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
return result;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
setMasterIndexZoneOpenChapter(index->masterIndex, zone->id,
|
|
Packit Service |
310c69 |
zone->newestVirtualChapter);
|
|
Packit Service |
310c69 |
return UDS_SUCCESS;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
int executeSparseCacheBarrierMessage(IndexZone *zone,
|
|
Packit Service |
310c69 |
BarrierMessageData *barrier)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
/*
|
|
Packit Service |
310c69 |
* Check if the chapter index for the virtual chapter is already in the
|
|
Packit Service |
310c69 |
* cache, and if it's not, rendezvous with the other zone threads to add the
|
|
Packit Service |
310c69 |
* chapter index to the sparse index cache.
|
|
Packit Service |
310c69 |
*/
|
|
Packit Service |
310c69 |
return updateSparseCache(zone, barrier->virtualChapter);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Handle notification that some other zone has closed its open chapter. If
|
|
Packit Service |
310c69 |
* the chapter that was closed is still the open chapter for this zone,
|
|
Packit Service |
310c69 |
* close it now in order to minimize skew.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param zone The zone receiving the notification
|
|
Packit Service |
310c69 |
* @param chapterClosed The notification
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @return UDS_SUCCESS or an error code
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static int handleChapterClosed(IndexZone *zone,
|
|
Packit Service |
310c69 |
ChapterClosedMessageData *chapterClosed)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
if (zone->newestVirtualChapter == chapterClosed->virtualChapter) {
|
|
Packit Service |
310c69 |
return openNextChapter(zone, NULL);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
return UDS_SUCCESS;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
int dispatchIndexZoneControlRequest(Request *request)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
ZoneMessage *message = &request->zoneMessage;
|
|
Packit Service |
310c69 |
IndexZone *zone = message->index->zones[request->zoneNumber];
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
switch (request->action) {
|
|
Packit Service |
310c69 |
case REQUEST_SPARSE_CACHE_BARRIER:
|
|
Packit Service |
310c69 |
return executeSparseCacheBarrierMessage(zone, &message->data.barrier);
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
case REQUEST_ANNOUNCE_CHAPTER_CLOSED:
|
|
Packit Service |
310c69 |
return handleChapterClosed(zone, &message->data.chapterClosed);
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
default:
|
|
Packit Service |
310c69 |
return ASSERT_FALSE("valid control message type: %d", request->action);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Announce the closure of the current open chapter to the other zones.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param request The request which caused the chapter to close
|
|
Packit Service |
310c69 |
* (may be NULL)
|
|
Packit Service |
310c69 |
* @param zone The zone which first closed the chapter
|
|
Packit Service |
310c69 |
* @param closedChapter The chapter which was closed
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @return UDS_SUCCESS or an error code
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static int announceChapterClosed(Request *request,
|
|
Packit Service |
310c69 |
IndexZone *zone,
|
|
Packit Service |
310c69 |
uint64_t closedChapter)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
IndexRouter *router = ((request != NULL) ? request->router : NULL);
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
ZoneMessage zoneMessage = {
|
|
Packit Service |
310c69 |
.index = zone->index,
|
|
Packit Service |
310c69 |
.data = {
|
|
Packit Service |
310c69 |
.chapterClosed = { .virtualChapter = closedChapter }
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
};
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
unsigned int i;
|
|
Packit Service |
310c69 |
for (i = 0; i < zone->index->zoneCount; i++) {
|
|
Packit Service |
310c69 |
if (zone->id == i) {
|
|
Packit Service |
310c69 |
continue;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
int result;
|
|
Packit Service |
310c69 |
if (router != NULL) {
|
|
Packit Service |
310c69 |
result = launchZoneControlMessage(REQUEST_ANNOUNCE_CHAPTER_CLOSED,
|
|
Packit Service |
310c69 |
zoneMessage, i, router);
|
|
Packit Service |
310c69 |
} else {
|
|
Packit Service |
310c69 |
// We're in a test which doesn't have zone queues, so we can just
|
|
Packit Service |
310c69 |
// call the message function directly.
|
|
Packit Service |
310c69 |
result = handleChapterClosed(zone->index->zones[i],
|
|
Packit Service |
310c69 |
&zoneMessage.data.chapterClosed);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
if (result != UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
return result;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
return UDS_SUCCESS;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
int openNextChapter(IndexZone *zone, Request *request)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
logDebug("closing chapter %llu of zone %d after %u entries (%u short)",
|
|
Packit Service |
310c69 |
zone->newestVirtualChapter, zone->id, zone->openChapter->size,
|
|
Packit Service |
310c69 |
zone->openChapter->capacity - zone->openChapter->size);
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
int result = swapOpenChapter(zone);
|
|
Packit Service |
310c69 |
if (result != UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
return result;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
uint64_t closedChapter = zone->newestVirtualChapter++;
|
|
Packit Service |
310c69 |
result = reapOldestChapter(zone);
|
|
Packit Service |
310c69 |
if (result != UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
return logUnrecoverable(result, "reapOldestChapter failed");
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
resetOpenChapter(zone->openChapter);
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
// begin, continue, or finish the checkpoint processing
|
|
Packit Service |
310c69 |
// moved above startClosingChapter because some of the
|
|
Packit Service |
310c69 |
// checkpoint processing now done by the chapter writer thread
|
|
Packit Service |
310c69 |
result = processCheckpointing(zone->index,
|
|
Packit Service |
310c69 |
zone->id,
|
|
Packit Service |
310c69 |
zone->newestVirtualChapter);
|
|
Packit Service |
310c69 |
if (result != UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
return result;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
unsigned int finishedZones = startClosingChapter(zone->index->chapterWriter,
|
|
Packit Service |
310c69 |
zone->id,
|
|
Packit Service |
310c69 |
zone->writingChapter);
|
|
Packit Service |
310c69 |
if ((finishedZones == 1) && (zone->index->zoneCount > 1)) {
|
|
Packit Service |
310c69 |
// This is the first zone of a multi-zone index to close this chapter,
|
|
Packit Service |
310c69 |
// so inform the other zones in order to control zone skew.
|
|
Packit Service |
310c69 |
result = announceChapterClosed(request, zone, closedChapter);
|
|
Packit Service |
310c69 |
if (result != UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
return result;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
// If the chapter being opened won't overwrite the oldest chapter, we're
|
|
Packit Service |
310c69 |
// done.
|
|
Packit Service |
310c69 |
if (!areSamePhysicalChapter(zone->index->volume->geometry,
|
|
Packit Service |
310c69 |
zone->newestVirtualChapter,
|
|
Packit Service |
310c69 |
zone->oldestVirtualChapter)) {
|
|
Packit Service |
310c69 |
return UDS_SUCCESS;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
uint64_t victim = zone->oldestVirtualChapter++;
|
|
Packit Service |
310c69 |
if (finishedZones < zone->index->zoneCount) {
|
|
Packit Service |
310c69 |
// We are not the last zone to close the chapter, so we're done
|
|
Packit Service |
310c69 |
return UDS_SUCCESS;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/*
|
|
Packit Service |
310c69 |
* We are the last zone to close the chapter, so clean up the cache. That
|
|
Packit Service |
310c69 |
* it is safe to let the last thread out of the previous chapter to do this
|
|
Packit Service |
310c69 |
* relies on the fact that although the new open chapter shadows the oldest
|
|
Packit Service |
310c69 |
* chapter in the cache, until we write the new open chapter to disk, we'll
|
|
Packit Service |
310c69 |
* never look for it in the cache.
|
|
Packit Service |
310c69 |
*/
|
|
Packit Service |
310c69 |
return forgetChapter(zone->index->volume, victim, INVALIDATION_EXPIRE);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
IndexRegion computeIndexRegion(const IndexZone *zone,
|
|
Packit Service |
310c69 |
uint64_t virtualChapter)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
if (virtualChapter == zone->newestVirtualChapter) {
|
|
Packit Service |
310c69 |
return LOC_IN_OPEN_CHAPTER;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
return (isZoneChapterSparse(zone, virtualChapter)
|
|
Packit Service |
310c69 |
? LOC_IN_SPARSE : LOC_IN_DENSE);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
int getRecordFromZone(IndexZone *zone,
|
|
Packit Service |
310c69 |
Request *request,
|
|
Packit Service |
310c69 |
bool *found,
|
|
Packit Service |
310c69 |
uint64_t virtualChapter)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
if (virtualChapter == zone->newestVirtualChapter) {
|
|
Packit Service |
310c69 |
searchOpenChapter(zone->openChapter, &request->chunkName,
|
|
Packit Service |
310c69 |
&request->oldMetadata, found);
|
|
Packit Service |
310c69 |
return UDS_SUCCESS;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
if ((zone->newestVirtualChapter > 0)
|
|
Packit Service |
310c69 |
&& (virtualChapter == (zone->newestVirtualChapter - 1))
|
|
Packit Service |
310c69 |
&& (zone->writingChapter->size > 0)) {
|
|
Packit Service |
310c69 |
// Only search the writing chapter if it is full, else look on disk.
|
|
Packit Service |
310c69 |
searchOpenChapter(zone->writingChapter, &request->chunkName,
|
|
Packit Service |
310c69 |
&request->oldMetadata, found);
|
|
Packit Service |
310c69 |
return UDS_SUCCESS;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
// The slow lane thread has determined the location previously. We don't need
|
|
Packit Service |
310c69 |
// to search again. Just return the location.
|
|
Packit Service |
310c69 |
if (request->slLocationKnown) {
|
|
Packit Service |
310c69 |
*found = request->slLocation != LOC_UNAVAILABLE;
|
|
Packit Service |
310c69 |
return UDS_SUCCESS;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
Volume *volume = zone->index->volume;
|
|
Packit Service |
310c69 |
if (isZoneChapterSparse(zone, virtualChapter)
|
|
Packit Service |
310c69 |
&& sparseCacheContains(volume->sparseCache, virtualChapter,
|
|
Packit Service |
310c69 |
request->zoneNumber)) {
|
|
Packit Service |
310c69 |
// The named chunk, if it exists, is in a sparse chapter that is cached,
|
|
Packit Service |
310c69 |
// so just run the chunk through the sparse chapter cache search.
|
|
Packit Service |
310c69 |
return searchSparseCacheInZone(zone, request, virtualChapter, found);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
return searchVolumePageCache(volume, request, &request->chunkName,
|
|
Packit Service |
310c69 |
virtualChapter, &request->oldMetadata, found);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
int putRecordInZone(IndexZone *zone,
|
|
Packit Service |
310c69 |
Request *request,
|
|
Packit Service |
310c69 |
const UdsChunkData *metadata)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
unsigned int remaining;
|
|
Packit Service |
310c69 |
int result = putOpenChapter(zone->openChapter, &request->chunkName, metadata,
|
|
Packit Service |
310c69 |
&remaining);
|
|
Packit Service |
310c69 |
if (result != UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
return result;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
if (remaining == 0) {
|
|
Packit Service |
310c69 |
return openNextChapter(zone, request);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
return UDS_SUCCESS;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**************************************************************************/
|
|
Packit Service |
310c69 |
int searchSparseCacheInZone(IndexZone *zone,
|
|
Packit Service |
310c69 |
Request *request,
|
|
Packit Service |
310c69 |
uint64_t virtualChapter,
|
|
Packit Service |
310c69 |
bool *found)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
int recordPageNumber;
|
|
Packit Service |
310c69 |
int result = searchSparseCache(zone, &request->chunkName, &virtualChapter,
|
|
Packit Service |
310c69 |
&recordPageNumber);
|
|
Packit Service |
310c69 |
if ((result != UDS_SUCCESS) || (virtualChapter == UINT64_MAX)) {
|
|
Packit Service |
310c69 |
return result;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
Volume *volume = zone->index->volume;
|
|
Packit Service |
310c69 |
// XXX map to physical chapter and validate. It would be nice to just pass
|
|
Packit Service |
310c69 |
// the virtual in to the slow lane, since it's tracking invalidations.
|
|
Packit Service |
310c69 |
unsigned int chapter
|
|
Packit Service |
310c69 |
= mapToPhysicalChapter(volume->geometry, virtualChapter);
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
return searchCachedRecordPage(volume, request, &request->chunkName, chapter,
|
|
Packit Service |
310c69 |
recordPageNumber, &request->oldMetadata,
|
|
Packit Service |
310c69 |
found);
|
|
Packit Service |
310c69 |
}
|