|
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/masterIndexOps.c#4 $
|
|
Packit Service |
310c69 |
*/
|
|
Packit Service |
310c69 |
#include "masterIndexOps.h"
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
#include "compiler.h"
|
|
Packit Service |
310c69 |
#include "errors.h"
|
|
Packit Service |
310c69 |
#include "indexComponent.h"
|
|
Packit Service |
310c69 |
#include "logger.h"
|
|
Packit Service |
310c69 |
#include "masterIndex005.h"
|
|
Packit Service |
310c69 |
#include "masterIndex006.h"
|
|
Packit Service |
310c69 |
#include "memoryAlloc.h"
|
|
Packit Service |
310c69 |
#include "permassert.h"
|
|
Packit Service |
310c69 |
#include "uds.h"
|
|
Packit Service |
310c69 |
#include "zone.h"
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
static INLINE bool usesSparse(const Configuration *config)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
return config->geometry->sparseChaptersPerVolume > 0;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
void getMasterIndexCombinedStats(const MasterIndex *masterIndex,
|
|
Packit Service |
310c69 |
MasterIndexStats *stats)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
MasterIndexStats dense, sparse;
|
|
Packit Service |
310c69 |
getMasterIndexStats(masterIndex, &dense, &sparse);
|
|
Packit Service |
310c69 |
stats->memoryAllocated = dense.memoryAllocated + sparse.memoryAllocated;
|
|
Packit Service |
310c69 |
stats->rebalanceTime = dense.rebalanceTime + sparse.rebalanceTime;
|
|
Packit Service |
310c69 |
stats->rebalanceCount = dense.rebalanceCount + sparse.rebalanceCount;
|
|
Packit Service |
310c69 |
stats->recordCount = dense.recordCount + sparse.recordCount;
|
|
Packit Service |
310c69 |
stats->collisionCount = dense.collisionCount + sparse.collisionCount;
|
|
Packit Service |
310c69 |
stats->discardCount = dense.discardCount + sparse.discardCount;
|
|
Packit Service |
310c69 |
stats->overflowCount = dense.overflowCount + sparse.overflowCount;
|
|
Packit Service |
310c69 |
stats->numLists = dense.numLists + sparse.numLists;
|
|
Packit Service |
310c69 |
stats->earlyFlushes = dense.earlyFlushes + sparse.earlyFlushes;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
int makeMasterIndex(const Configuration *config, unsigned int numZones,
|
|
Packit Service |
310c69 |
uint64_t volumeNonce, MasterIndex **masterIndex)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
if (usesSparse(config)) {
|
|
Packit Service |
310c69 |
return makeMasterIndex006(config, numZones, volumeNonce, masterIndex);
|
|
Packit Service |
310c69 |
} else {
|
|
Packit Service |
310c69 |
return makeMasterIndex005(config, numZones, volumeNonce, masterIndex);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
int computeMasterIndexSaveBlocks(const Configuration *config,
|
|
Packit Service |
310c69 |
size_t blockSize, uint64_t *blockCount)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
size_t numBytes;
|
|
Packit Service |
310c69 |
int result = (usesSparse(config)
|
|
Packit Service |
310c69 |
? computeMasterIndexSaveBytes006(config, &numBytes)
|
|
Packit Service |
310c69 |
: computeMasterIndexSaveBytes005(config, &numBytes));
|
|
Packit Service |
310c69 |
if (result != UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
return result;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
numBytes += sizeof(DeltaListSaveInfo);
|
|
Packit Service |
310c69 |
*blockCount = (numBytes + blockSize - 1) / blockSize + MAX_ZONES;
|
|
Packit Service |
310c69 |
return UDS_SUCCESS;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
static int readMasterIndex(ReadPortal *portal)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
MasterIndex *masterIndex = indexComponentContext(portal->component);
|
|
Packit Service |
310c69 |
unsigned int numZones = portal->zones;
|
|
Packit Service |
310c69 |
if (numZones > MAX_ZONES) {
|
|
Packit Service |
310c69 |
return logErrorWithStringError(UDS_BAD_STATE,
|
|
Packit Service |
310c69 |
"zone count %u must not exceed MAX_ZONES",
|
|
Packit Service |
310c69 |
numZones);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
BufferedReader *readers[MAX_ZONES];
|
|
Packit Service |
310c69 |
unsigned int z;
|
|
Packit Service |
310c69 |
for (z = 0; z < numZones; ++z) {
|
|
Packit Service |
310c69 |
int result = getBufferedReaderForPortal(portal, z, &readers[z]);
|
|
Packit Service |
310c69 |
if (result != UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
return logErrorWithStringError(result,
|
|
Packit Service |
310c69 |
"cannot read component for zone %u", z);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
return restoreMasterIndex(readers, numZones, masterIndex);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
static int writeMasterIndex(IndexComponent *component,
|
|
Packit Service |
310c69 |
BufferedWriter *writer,
|
|
Packit Service |
310c69 |
unsigned int zone,
|
|
Packit Service |
310c69 |
IncrementalWriterCommand command,
|
|
Packit Service |
310c69 |
bool *completed)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
MasterIndex *masterIndex = indexComponentContext(component);
|
|
Packit Service |
310c69 |
bool isComplete = false;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
int result = UDS_SUCCESS;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
switch (command) {
|
|
Packit Service |
310c69 |
case IWC_START:
|
|
Packit Service |
310c69 |
result = startSavingMasterIndex(masterIndex, zone, writer);
|
|
Packit Service |
310c69 |
isComplete = result != UDS_SUCCESS;
|
|
Packit Service |
310c69 |
break;
|
|
Packit Service |
310c69 |
case IWC_CONTINUE:
|
|
Packit Service |
310c69 |
isComplete = isSavingMasterIndexDone(masterIndex, zone);
|
|
Packit Service |
310c69 |
break;
|
|
Packit Service |
310c69 |
case IWC_FINISH:
|
|
Packit Service |
310c69 |
result = finishSavingMasterIndex(masterIndex, zone);
|
|
Packit Service |
310c69 |
if (result == UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
result = writeGuardDeltaList(writer);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
isComplete = true;
|
|
Packit Service |
310c69 |
break;
|
|
Packit Service |
310c69 |
case IWC_ABORT:
|
|
Packit Service |
310c69 |
result = abortSavingMasterIndex(masterIndex, zone);
|
|
Packit Service |
310c69 |
isComplete = true;
|
|
Packit Service |
310c69 |
break;
|
|
Packit Service |
310c69 |
default:
|
|
Packit Service |
310c69 |
result = logWarningWithStringError(UDS_INVALID_ARGUMENT,
|
|
Packit Service |
310c69 |
"Invalid writer command");
|
|
Packit Service |
310c69 |
break;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
if (completed != NULL) {
|
|
Packit Service |
310c69 |
*completed = isComplete;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
return result;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
static const IndexComponentInfo MASTER_INDEX_INFO_DATA = {
|
|
Packit Service |
310c69 |
.kind = RL_KIND_MASTER_INDEX,
|
|
Packit Service |
310c69 |
.name = "master index",
|
|
Packit Service |
310c69 |
.saveOnly = false,
|
|
Packit Service |
310c69 |
.chapterSync = false,
|
|
Packit Service |
310c69 |
.multiZone = true,
|
|
Packit Service |
310c69 |
.ioStorage = true,
|
|
Packit Service |
310c69 |
.loader = readMasterIndex,
|
|
Packit Service |
310c69 |
.saver = NULL,
|
|
Packit Service |
310c69 |
.incremental = writeMasterIndex,
|
|
Packit Service |
310c69 |
};
|
|
Packit Service |
310c69 |
const IndexComponentInfo *const MASTER_INDEX_INFO = &MASTER_INDEX_INFO_DATA;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
static int restoreMasterIndexBody(BufferedReader **bufferedReaders,
|
|
Packit Service |
310c69 |
unsigned int numReaders,
|
|
Packit Service |
310c69 |
MasterIndex *masterIndex,
|
|
Packit Service |
310c69 |
byte dlData[DELTA_LIST_MAX_BYTE_COUNT])
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
// Start by reading the "header" section of the stream
|
|
Packit Service |
310c69 |
int result = startRestoringMasterIndex(masterIndex, bufferedReaders,
|
|
Packit Service |
310c69 |
numReaders);
|
|
Packit Service |
310c69 |
if (result != UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
return result;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
// Loop to read the delta lists, stopping when they have all been processed.
|
|
Packit Service |
310c69 |
unsigned int z;
|
|
Packit Service |
310c69 |
for (z = 0; z < numReaders; z++) {
|
|
Packit Service |
310c69 |
for (;;) {
|
|
Packit Service |
310c69 |
DeltaListSaveInfo dlsi;
|
|
Packit Service |
310c69 |
result = readSavedDeltaList(&dlsi, dlData, bufferedReaders[z]);
|
|
Packit Service |
310c69 |
if (result == UDS_END_OF_FILE) {
|
|
Packit Service |
310c69 |
break;
|
|
Packit Service |
310c69 |
} else if (result != UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
abortRestoringMasterIndex(masterIndex);
|
|
Packit Service |
310c69 |
return result;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
result = restoreDeltaListToMasterIndex(masterIndex, &dlsi, dlData);
|
|
Packit Service |
310c69 |
if (result != UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
abortRestoringMasterIndex(masterIndex);
|
|
Packit Service |
310c69 |
return result;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
if (!isRestoringMasterIndexDone(masterIndex)) {
|
|
Packit Service |
310c69 |
abortRestoringMasterIndex(masterIndex);
|
|
Packit Service |
310c69 |
return logWarningWithStringError(UDS_CORRUPT_COMPONENT,
|
|
Packit Service |
310c69 |
"incomplete delta list data");
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
return UDS_SUCCESS;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
int restoreMasterIndex(BufferedReader **bufferedReaders,
|
|
Packit Service |
310c69 |
unsigned int numReaders,
|
|
Packit Service |
310c69 |
MasterIndex *masterIndex)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
byte *dlData;
|
|
Packit Service |
310c69 |
int result = ALLOCATE(DELTA_LIST_MAX_BYTE_COUNT, byte, __func__, &dlData);
|
|
Packit Service |
310c69 |
if (result != UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
return result;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
result = restoreMasterIndexBody(bufferedReaders, numReaders, masterIndex,
|
|
Packit Service |
310c69 |
dlData);
|
|
Packit Service |
310c69 |
FREE(dlData);
|
|
Packit Service |
310c69 |
return result;
|
|
Packit Service |
310c69 |
}
|