|
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/masterIndex006.c#2 $
|
|
Packit Service |
310c69 |
*/
|
|
Packit Service |
310c69 |
#include "masterIndex006.h"
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
#include "buffer.h"
|
|
Packit Service |
310c69 |
#include "compiler.h"
|
|
Packit Service |
310c69 |
#include "errors.h"
|
|
Packit Service |
310c69 |
#include "hashUtils.h"
|
|
Packit Service |
310c69 |
#include "logger.h"
|
|
Packit Service |
310c69 |
#include "masterIndex005.h"
|
|
Packit Service |
310c69 |
#include "memoryAlloc.h"
|
|
Packit Service |
310c69 |
#include "permassert.h"
|
|
Packit Service |
310c69 |
#include "threads.h"
|
|
Packit Service |
310c69 |
#include "uds.h"
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/*
|
|
Packit Service |
310c69 |
* The master index is a kept as a wrapper around 2 master index
|
|
Packit Service |
310c69 |
* implementations, one for dense chapters and one for sparse chapters.
|
|
Packit Service |
310c69 |
* Methods will be routed to one or the other, or both, depending on the
|
|
Packit Service |
310c69 |
* method and data passed in.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* The master index is divided into zones, and in normal operation there is
|
|
Packit Service |
310c69 |
* one thread operating on each zone. Any operation that operates on all
|
|
Packit Service |
310c69 |
* the zones needs to do its operation at a safe point that ensures that
|
|
Packit Service |
310c69 |
* only one thread is operating on the master index.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* The only multithreaded operation supported by the sparse master index is
|
|
Packit Service |
310c69 |
* the lookupMasterIndexName() method. It is called by the thread that
|
|
Packit Service |
310c69 |
* assigns an index request to the proper zone, and needs to do a master
|
|
Packit Service |
310c69 |
* index query for sampled chunk names. The zone mutexes are used to make
|
|
Packit Service |
310c69 |
* this lookup operation safe.
|
|
Packit Service |
310c69 |
*/
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
typedef struct __attribute__((aligned(CACHE_LINE_BYTES))) masterIndexZone {
|
|
Packit Service |
310c69 |
Mutex hookMutex; // Protects the sampled index in this zone
|
|
Packit Service |
310c69 |
} MasterIndexZone;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
typedef struct {
|
|
Packit Service |
310c69 |
MasterIndex common; // Common master index methods
|
|
Packit Service |
310c69 |
unsigned int sparseSampleRate; // The sparse sample rate
|
|
Packit Service |
310c69 |
unsigned int numZones; // The number of zones
|
|
Packit Service |
310c69 |
MasterIndex *miNonHook; // The non-hook index
|
|
Packit Service |
310c69 |
MasterIndex *miHook; // The hook index == sample index
|
|
Packit Service |
310c69 |
MasterIndexZone *masterZones; // The zones
|
|
Packit Service |
310c69 |
} MasterIndex6;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Determine whether a given chunk name is a hook.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param masterIndex The master index
|
|
Packit Service |
310c69 |
* @param name The block name
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @return whether to use as sample
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static INLINE bool isMasterIndexSample_006(const MasterIndex *masterIndex,
|
|
Packit Service |
310c69 |
const UdsChunkName *name)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
const MasterIndex6 *mi6 = const_container_of(masterIndex, MasterIndex6,
|
|
Packit Service |
310c69 |
common);
|
|
Packit Service |
310c69 |
return (extractSamplingBytes(name) % mi6->sparseSampleRate) == 0;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/***********************************************************************/
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Get the subindex for the given chunk name
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param masterIndex The master index
|
|
Packit Service |
310c69 |
* @param name The block name
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @return the subindex
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static INLINE MasterIndex *getSubIndex(const MasterIndex *masterIndex,
|
|
Packit Service |
310c69 |
const UdsChunkName *name)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
const MasterIndex6 *mi6 = const_container_of(masterIndex, MasterIndex6,
|
|
Packit Service |
310c69 |
common);
|
|
Packit Service |
310c69 |
return (isMasterIndexSample_006(masterIndex, name)
|
|
Packit Service |
310c69 |
? mi6->miHook
|
|
Packit Service |
310c69 |
: mi6->miNonHook);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/***********************************************************************/
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Terminate and clean up the master index
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param masterIndex The master index to terminate
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static void freeMasterIndex_006(MasterIndex *masterIndex)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
if (masterIndex != NULL) {
|
|
Packit Service |
310c69 |
MasterIndex6 *mi6 = container_of(masterIndex, MasterIndex6, common);
|
|
Packit Service |
310c69 |
if (mi6->masterZones != NULL) {
|
|
Packit Service |
310c69 |
unsigned int zone;
|
|
Packit Service |
310c69 |
for (zone = 0; zone < mi6->numZones; zone++) {
|
|
Packit Service |
310c69 |
destroyMutex(&mi6->masterZones[zone].hookMutex);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
FREE(mi6->masterZones);
|
|
Packit Service |
310c69 |
mi6->masterZones = NULL;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
if (mi6->miNonHook != NULL) {
|
|
Packit Service |
310c69 |
freeMasterIndex(mi6->miNonHook);
|
|
Packit Service |
310c69 |
mi6->miNonHook = NULL;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
if (mi6->miHook != NULL) {
|
|
Packit Service |
310c69 |
freeMasterIndex(mi6->miHook);
|
|
Packit Service |
310c69 |
mi6->miHook = NULL;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
FREE(masterIndex);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/***********************************************************************/
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Constants and structures for the saved master index file. "MI6" is for
|
|
Packit Service |
310c69 |
* masterIndex006, and "-XXXX" is a number to increment when the format of
|
|
Packit Service |
310c69 |
* the data changes.
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
enum { MAGIC_SIZE = 8 };
|
|
Packit Service |
310c69 |
static const char MAGIC_MI_START[] = "MI6-0001";
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
struct mi006_data {
|
|
Packit Service |
310c69 |
char magic[MAGIC_SIZE]; // MAGIC_MI_START
|
|
Packit Service |
310c69 |
unsigned int sparseSampleRate;
|
|
Packit Service |
310c69 |
};
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/***********************************************************************/
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Set the tag value used when saving and/or restoring a master index.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param masterIndex The master index
|
|
Packit Service |
310c69 |
* @param tag The tag value
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static void setMasterIndexTag_006(MasterIndex *masterIndex
|
|
Packit Service |
310c69 |
__attribute__((unused)),
|
|
Packit Service |
310c69 |
byte tag __attribute__((unused)))
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/***********************************************************************/
|
|
Packit Service |
310c69 |
__attribute__((warn_unused_result))
|
|
Packit Service |
310c69 |
static int encodeMasterIndexHeader(Buffer *buffer, struct mi006_data *header)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
int result = putBytes(buffer, MAGIC_SIZE, MAGIC_MI_START);
|
|
Packit Service |
310c69 |
if (result != UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
return result;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
result = putUInt32LEIntoBuffer(buffer, header->sparseSampleRate);
|
|
Packit Service |
310c69 |
if (result != UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
return result;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
result = ASSERT_LOG_ONLY(contentLength(buffer) == sizeof(struct mi006_data),
|
|
Packit Service |
310c69 |
"%zu bytes of config written, of %zu expected",
|
|
Packit Service |
310c69 |
contentLength(buffer), sizeof(struct mi006_data));
|
|
Packit Service |
310c69 |
return result;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Start saving a master index to a buffered output stream.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param masterIndex The master index
|
|
Packit Service |
310c69 |
* @param zoneNumber The number of the zone to save
|
|
Packit Service |
310c69 |
* @param bufferedWriter The index state component being written
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @return UDS_SUCCESS on success, or an error code on failure
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static int startSavingMasterIndex_006(const MasterIndex *masterIndex,
|
|
Packit Service |
310c69 |
unsigned int zoneNumber,
|
|
Packit Service |
310c69 |
BufferedWriter *bufferedWriter)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
const MasterIndex6 *mi6 = const_container_of(masterIndex, MasterIndex6,
|
|
Packit Service |
310c69 |
common);
|
|
Packit Service |
310c69 |
Buffer *buffer;
|
|
Packit Service |
310c69 |
int result = makeBuffer(sizeof(struct mi006_data), &buffer);
|
|
Packit Service |
310c69 |
if (result != UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
return result;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
struct mi006_data header;
|
|
Packit Service |
310c69 |
memset(&header, 0, sizeof(header));
|
|
Packit Service |
310c69 |
memcpy(header.magic, MAGIC_MI_START, MAGIC_SIZE);
|
|
Packit Service |
310c69 |
header.sparseSampleRate = mi6->sparseSampleRate;
|
|
Packit Service |
310c69 |
result = encodeMasterIndexHeader(buffer, &header);
|
|
Packit Service |
310c69 |
if (result != UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
freeBuffer(&buffer);
|
|
Packit Service |
310c69 |
return result;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
result = writeToBufferedWriter(bufferedWriter, getBufferContents(buffer),
|
|
Packit Service |
310c69 |
contentLength(buffer));
|
|
Packit Service |
310c69 |
freeBuffer(&buffer);
|
|
Packit Service |
310c69 |
if (result != UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
logWarningWithStringError(result, "failed to write master index header");
|
|
Packit Service |
310c69 |
return result;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
result = startSavingMasterIndex(mi6->miNonHook, zoneNumber, bufferedWriter);
|
|
Packit Service |
310c69 |
if (result != UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
return result;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
result = startSavingMasterIndex(mi6->miHook, zoneNumber, bufferedWriter);
|
|
Packit Service |
310c69 |
if (result != UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
return result;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
return UDS_SUCCESS;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/***********************************************************************/
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Have all the data been written while saving a master index to an output
|
|
Packit Service |
310c69 |
* stream? If the answer is yes, it is still necessary to call
|
|
Packit Service |
310c69 |
* finishSavingMasterIndex(), which will return quickly.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param masterIndex The master index
|
|
Packit Service |
310c69 |
* @param zoneNumber The number of the zone to save
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @return true if all the data are written
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static bool isSavingMasterIndexDone_006(const MasterIndex *masterIndex,
|
|
Packit Service |
310c69 |
unsigned int zoneNumber)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
const MasterIndex6 *mi6 = const_container_of(masterIndex, MasterIndex6,
|
|
Packit Service |
310c69 |
common);
|
|
Packit Service |
310c69 |
return (isSavingMasterIndexDone(mi6->miNonHook, zoneNumber)
|
|
Packit Service |
310c69 |
&& isSavingMasterIndexDone(mi6->miHook, zoneNumber));
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/***********************************************************************/
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Finish saving a master index to an output stream. Force the writing of
|
|
Packit Service |
310c69 |
* all of the remaining data. If an error occurred asynchronously during
|
|
Packit Service |
310c69 |
* the save operation, it will be returned here.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param masterIndex The master index
|
|
Packit Service |
310c69 |
* @param zoneNumber The number of the zone to save
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @return UDS_SUCCESS on success, or an error code on failure
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static int finishSavingMasterIndex_006(const MasterIndex *masterIndex,
|
|
Packit Service |
310c69 |
unsigned int zoneNumber)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
const MasterIndex6 *mi6 = const_container_of(masterIndex, MasterIndex6,
|
|
Packit Service |
310c69 |
common);
|
|
Packit Service |
310c69 |
int result = finishSavingMasterIndex(mi6->miNonHook, zoneNumber);
|
|
Packit Service |
310c69 |
if (result == UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
result = finishSavingMasterIndex(mi6->miHook, zoneNumber);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
return result;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/***********************************************************************/
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Abort saving a master index to an output stream. If an error occurred
|
|
Packit Service |
310c69 |
* asynchronously during the save operation, it will be dropped.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param masterIndex The master index
|
|
Packit Service |
310c69 |
* @param zoneNumber The number of the zone to save
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @return UDS_SUCCESS on success, or an error code on failure
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static int abortSavingMasterIndex_006(const MasterIndex *masterIndex,
|
|
Packit Service |
310c69 |
unsigned int zoneNumber)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
const MasterIndex6 *mi6 = const_container_of(masterIndex, MasterIndex6,
|
|
Packit Service |
310c69 |
common);
|
|
Packit Service |
310c69 |
int result = abortSavingMasterIndex(mi6->miNonHook, zoneNumber);
|
|
Packit Service |
310c69 |
int result2 = abortSavingMasterIndex(mi6->miHook, zoneNumber);
|
|
Packit Service |
310c69 |
if (result == UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
result = result2;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
return result;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/***********************************************************************/
|
|
Packit Service |
310c69 |
__attribute__((warn_unused_result))
|
|
Packit Service |
310c69 |
static int decodeMasterIndexHeader(Buffer *buffer, struct mi006_data *header)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
int result = getBytesFromBuffer(buffer, sizeof(header->magic),
|
|
Packit Service |
310c69 |
&header->magic);
|
|
Packit Service |
310c69 |
if (result != UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
return result;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
result = getUInt32LEFromBuffer(buffer, &header->sparseSampleRate);
|
|
Packit Service |
310c69 |
if (result != UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
return result;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
result = ASSERT_LOG_ONLY(contentLength(buffer) == 0,
|
|
Packit Service |
310c69 |
"%zu bytes decoded of %zu expected",
|
|
Packit Service |
310c69 |
bufferLength(buffer) - contentLength(buffer),
|
|
Packit Service |
310c69 |
bufferLength(buffer));
|
|
Packit Service |
310c69 |
if (result != UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
result = UDS_CORRUPT_COMPONENT;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
return result;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Start restoring the master index from multiple buffered readers
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param masterIndex The master index to restore into
|
|
Packit Service |
310c69 |
* @param bufferedReaders The buffered reader to read the master index from
|
|
Packit Service |
310c69 |
* @param numReaders The number of buffered readers
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @return UDS_SUCCESS on success, or an error code on failure
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static int startRestoringMasterIndex_006(MasterIndex *masterIndex,
|
|
Packit Service |
310c69 |
BufferedReader **bufferedReaders,
|
|
Packit Service |
310c69 |
int numReaders)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
MasterIndex6 *mi6 = container_of(masterIndex, MasterIndex6, common);
|
|
Packit Service |
310c69 |
int result = ASSERT_WITH_ERROR_CODE(masterIndex != NULL, UDS_BAD_STATE,
|
|
Packit Service |
310c69 |
"cannot restore to null master index");
|
|
Packit Service |
310c69 |
if (result != UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
return result;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
int i;
|
|
Packit Service |
310c69 |
for (i = 0; i < numReaders; i++) {
|
|
Packit Service |
310c69 |
Buffer *buffer;
|
|
Packit Service |
310c69 |
result = makeBuffer(sizeof(struct mi006_data), &buffer);
|
|
Packit Service |
310c69 |
if (result != UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
return result;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
result = readFromBufferedReader(bufferedReaders[i],
|
|
Packit Service |
310c69 |
getBufferContents(buffer),
|
|
Packit Service |
310c69 |
bufferLength(buffer));
|
|
Packit Service |
310c69 |
if (result != UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
freeBuffer(&buffer);
|
|
Packit Service |
310c69 |
return logWarningWithStringError(result,
|
|
Packit Service |
310c69 |
"failed to read master index header");
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
result = resetBufferEnd(buffer, bufferLength(buffer));
|
|
Packit Service |
310c69 |
if (result != UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
freeBuffer(&buffer);
|
|
Packit Service |
310c69 |
return result;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
struct mi006_data header;
|
|
Packit Service |
310c69 |
result = decodeMasterIndexHeader(buffer, &header);
|
|
Packit Service |
310c69 |
freeBuffer(&buffer);
|
|
Packit Service |
310c69 |
if (result != UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
return result;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
if (memcmp(header.magic, MAGIC_MI_START, MAGIC_SIZE) != 0) {
|
|
Packit Service |
310c69 |
return logWarningWithStringError(UDS_CORRUPT_COMPONENT,
|
|
Packit Service |
310c69 |
"master index file had bad magic"
|
|
Packit Service |
310c69 |
" number");
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
if (i == 0) {
|
|
Packit Service |
310c69 |
mi6->sparseSampleRate = header.sparseSampleRate;
|
|
Packit Service |
310c69 |
} else if (mi6->sparseSampleRate != header.sparseSampleRate) {
|
|
Packit Service |
310c69 |
logWarningWithStringError(UDS_CORRUPT_COMPONENT,
|
|
Packit Service |
310c69 |
"Inconsistent sparse sample rate in delta"
|
|
Packit Service |
310c69 |
" index zone files: %u vs. %u",
|
|
Packit Service |
310c69 |
mi6->sparseSampleRate,
|
|
Packit Service |
310c69 |
header.sparseSampleRate);
|
|
Packit Service |
310c69 |
return UDS_CORRUPT_COMPONENT;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
result = startRestoringMasterIndex(mi6->miNonHook, bufferedReaders,
|
|
Packit Service |
310c69 |
numReaders);
|
|
Packit Service |
310c69 |
if (result != UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
return result;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
return startRestoringMasterIndex(mi6->miHook, bufferedReaders, numReaders);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/***********************************************************************/
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Have all the data been read while restoring a master index from an
|
|
Packit Service |
310c69 |
* input stream?
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param masterIndex The master index to restore into
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @return true if all the data are read
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static bool isRestoringMasterIndexDone_006(const MasterIndex *masterIndex)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
const MasterIndex6 *mi6 = const_container_of(masterIndex, MasterIndex6,
|
|
Packit Service |
310c69 |
common);
|
|
Packit Service |
310c69 |
return (isRestoringMasterIndexDone(mi6->miNonHook)
|
|
Packit Service |
310c69 |
&& isRestoringMasterIndexDone(mi6->miHook));
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/***********************************************************************/
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Restore a saved delta list
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param masterIndex The master index to restore into
|
|
Packit Service |
310c69 |
* @param dlsi The DeltaListSaveInfo describing the delta list
|
|
Packit Service |
310c69 |
* @param data The saved delta list bit stream
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @return error code or UDS_SUCCESS
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static int restoreDeltaListToMasterIndex_006(MasterIndex *masterIndex,
|
|
Packit Service |
310c69 |
const DeltaListSaveInfo *dlsi,
|
|
Packit Service |
310c69 |
const byte data[DELTA_LIST_MAX_BYTE_COUNT])
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
MasterIndex6 *mi6 = container_of(masterIndex, MasterIndex6, common);
|
|
Packit Service |
310c69 |
int result = restoreDeltaListToMasterIndex(mi6->miNonHook, dlsi, data);
|
|
Packit Service |
310c69 |
if (result != UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
result = restoreDeltaListToMasterIndex(mi6->miHook, dlsi, data);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
return result;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/***********************************************************************/
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Abort restoring a master index from an input stream.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param masterIndex The master index
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static void abortRestoringMasterIndex_006(MasterIndex *masterIndex)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
MasterIndex6 *mi6 = container_of(masterIndex, MasterIndex6, common);
|
|
Packit Service |
310c69 |
abortRestoringMasterIndex(mi6->miNonHook);
|
|
Packit Service |
310c69 |
abortRestoringMasterIndex(mi6->miHook);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/***********************************************************************/
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Set the open chapter number on a zone. The master index zone will be
|
|
Packit Service |
310c69 |
* modified to index the proper number of chapters ending with the new open
|
|
Packit Service |
310c69 |
* chapter.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param masterIndex The master index
|
|
Packit Service |
310c69 |
* @param zoneNumber The zone number
|
|
Packit Service |
310c69 |
* @param virtualChapter The new open chapter number
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static void setMasterIndexZoneOpenChapter_006(MasterIndex *masterIndex,
|
|
Packit Service |
310c69 |
unsigned int zoneNumber,
|
|
Packit Service |
310c69 |
uint64_t virtualChapter)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
MasterIndex6 *mi6 = container_of(masterIndex, MasterIndex6, common);
|
|
Packit Service |
310c69 |
setMasterIndexZoneOpenChapter(mi6->miNonHook, zoneNumber, virtualChapter);
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
// We need to prevent a lookupMasterIndexName() happening while we are
|
|
Packit Service |
310c69 |
// changing the open chapter number
|
|
Packit Service |
310c69 |
Mutex *mutex = &mi6->masterZones[zoneNumber].hookMutex;
|
|
Packit Service |
310c69 |
lockMutex(mutex);
|
|
Packit Service |
310c69 |
setMasterIndexZoneOpenChapter(mi6->miHook, zoneNumber, virtualChapter);
|
|
Packit Service |
310c69 |
unlockMutex(mutex);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/***********************************************************************/
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Set the open chapter number. The master index will be modified to index
|
|
Packit Service |
310c69 |
* the proper number of chapters ending with the new open chapter.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param masterIndex The master index
|
|
Packit Service |
310c69 |
* @param virtualChapter The new open chapter number
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static void setMasterIndexOpenChapter_006(MasterIndex *masterIndex,
|
|
Packit Service |
310c69 |
uint64_t virtualChapter)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
MasterIndex6 *mi6 = container_of(masterIndex, MasterIndex6, common);
|
|
Packit Service |
310c69 |
unsigned int zone;
|
|
Packit Service |
310c69 |
for (zone = 0; zone < mi6->numZones; zone++) {
|
|
Packit Service |
310c69 |
setMasterIndexZoneOpenChapter_006(masterIndex, zone, virtualChapter);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/***********************************************************************/
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Find the master index zone associated with a chunk name
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param masterIndex The master index
|
|
Packit Service |
310c69 |
* @param name The chunk name
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @return the zone that the chunk name belongs to
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static unsigned int getMasterIndexZone_006(const MasterIndex *masterIndex,
|
|
Packit Service |
310c69 |
const UdsChunkName *name)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
return getMasterIndexZone(getSubIndex(masterIndex, name), name);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/***********************************************************************/
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Do a quick read-only lookup of the chunk name and return information
|
|
Packit Service |
310c69 |
* needed by the index code to process the chunk name.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param masterIndex The master index
|
|
Packit Service |
310c69 |
* @param name The chunk name
|
|
Packit Service |
310c69 |
* @param triage Information about the chunk name
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @return UDS_SUCCESS or an error code
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static int lookupMasterIndexName_006(const MasterIndex *masterIndex,
|
|
Packit Service |
310c69 |
const UdsChunkName *name,
|
|
Packit Service |
310c69 |
MasterIndexTriage *triage)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
const MasterIndex6 *mi6 = const_container_of(masterIndex, MasterIndex6,
|
|
Packit Service |
310c69 |
common);
|
|
Packit Service |
310c69 |
triage->isSample = isMasterIndexSample_006(masterIndex, name);
|
|
Packit Service |
310c69 |
triage->inSampledChapter = false;
|
|
Packit Service |
310c69 |
triage->zone = getMasterIndexZone_006(masterIndex, name);
|
|
Packit Service |
310c69 |
int result = UDS_SUCCESS;
|
|
Packit Service |
310c69 |
if (triage->isSample) {
|
|
Packit Service |
310c69 |
Mutex *mutex = &mi6->masterZones[triage->zone].hookMutex;
|
|
Packit Service |
310c69 |
lockMutex(mutex);
|
|
Packit Service |
310c69 |
result = lookupMasterIndexSampledName(mi6->miHook, name, triage);
|
|
Packit Service |
310c69 |
unlockMutex(mutex);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
return result;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/***********************************************************************/
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Do a quick read-only lookup of the sampled chunk name and return
|
|
Packit Service |
310c69 |
* information needed by the index code to process the chunk name.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param masterIndex The master index
|
|
Packit Service |
310c69 |
* @param name The chunk name
|
|
Packit Service |
310c69 |
* @param triage Information about the chunk name. The zone and
|
|
Packit Service |
310c69 |
* isSample fields are already filled in. Set
|
|
Packit Service |
310c69 |
* inSampledChapter and virtualChapter if the chunk
|
|
Packit Service |
310c69 |
* name is found in the index.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @return UDS_SUCCESS or an error code
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static int lookupMasterIndexSampledName_006(const MasterIndex *masterIndex
|
|
Packit Service |
310c69 |
__attribute__((unused)),
|
|
Packit Service |
310c69 |
const UdsChunkName *name
|
|
Packit Service |
310c69 |
__attribute__((unused)),
|
|
Packit Service |
310c69 |
MasterIndexTriage *triage
|
|
Packit Service |
310c69 |
__attribute__((unused)))
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
return ASSERT_WITH_ERROR_CODE(false, UDS_BAD_STATE,
|
|
Packit Service |
310c69 |
"%s should not be called", __func__);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/***********************************************************************/
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Find the master index record associated with a block name
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* This is always the first routine to be called when dealing with a delta
|
|
Packit Service |
310c69 |
* master index entry. The fields of the record parameter should be
|
|
Packit Service |
310c69 |
* examined to determine the state of the record:
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* If isFound is false, then we did not find an entry for the block
|
|
Packit Service |
310c69 |
* name. Information is saved in the MasterIndexRecord so that
|
|
Packit Service |
310c69 |
* putMasterIndexRecord() will insert an entry for that block name at
|
|
Packit Service |
310c69 |
* the proper place.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* If isFound is true, then we did find an entry for the block name.
|
|
Packit Service |
310c69 |
* Information is saved in the MasterIndexRecord so that the "chapter"
|
|
Packit Service |
310c69 |
* and "isCollision" fields reflect the entry found.
|
|
Packit Service |
310c69 |
* Calls to removeMasterIndexRecord() will remove the entry, calls to
|
|
Packit Service |
310c69 |
* setMasterIndexRecordChapter() can modify the entry, and calls to
|
|
Packit Service |
310c69 |
* putMasterIndexRecord() can insert a collision record with this
|
|
Packit Service |
310c69 |
* entry.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param masterIndex The master index to search
|
|
Packit Service |
310c69 |
* @param name The chunk name
|
|
Packit Service |
310c69 |
* @param record Set to the info about the record searched for
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @return UDS_SUCCESS or an error code
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static int getMasterIndexRecord_006(MasterIndex *masterIndex,
|
|
Packit Service |
310c69 |
const UdsChunkName *name,
|
|
Packit Service |
310c69 |
MasterIndexRecord *record)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
const MasterIndex6 *mi6 = const_container_of(masterIndex, MasterIndex6,
|
|
Packit Service |
310c69 |
common);
|
|
Packit Service |
310c69 |
int result;
|
|
Packit Service |
310c69 |
if (isMasterIndexSample_006(masterIndex, name)) {
|
|
Packit Service |
310c69 |
/*
|
|
Packit Service |
310c69 |
* We need to prevent a lookupMasterIndexName() happening while we are
|
|
Packit Service |
310c69 |
* finding the master index record. Remember that because of lazy LRU
|
|
Packit Service |
310c69 |
* flushing of the master index, getMasterIndexRecord() is not a
|
|
Packit Service |
310c69 |
* read-only operation.
|
|
Packit Service |
310c69 |
*/
|
|
Packit Service |
310c69 |
unsigned int zone = getMasterIndexZone(mi6->miHook, name);
|
|
Packit Service |
310c69 |
Mutex *mutex = &mi6->masterZones[zone].hookMutex;
|
|
Packit Service |
310c69 |
lockMutex(mutex);
|
|
Packit Service |
310c69 |
result = getMasterIndexRecord(mi6->miHook, name, record);
|
|
Packit Service |
310c69 |
unlockMutex(mutex);
|
|
Packit Service |
310c69 |
// Remember the mutex so that other operations on the MasterIndexRecord
|
|
Packit Service |
310c69 |
// can use it
|
|
Packit Service |
310c69 |
record->mutex = mutex;
|
|
Packit Service |
310c69 |
} else {
|
|
Packit Service |
310c69 |
result = getMasterIndexRecord(mi6->miNonHook, name, record);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
return result;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/***********************************************************************/
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Get the number of bytes used for master index entries.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param masterIndex The master index
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @return The number of bytes in use
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static size_t getMasterIndexMemoryUsed_006(const MasterIndex *masterIndex)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
const MasterIndex6 *mi6 = const_container_of(masterIndex, MasterIndex6,
|
|
Packit Service |
310c69 |
common);
|
|
Packit Service |
310c69 |
return (getMasterIndexMemoryUsed(mi6->miNonHook)
|
|
Packit Service |
310c69 |
+ getMasterIndexMemoryUsed(mi6->miHook));
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/***********************************************************************/
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Return the master index stats. There is only one portion of the master
|
|
Packit Service |
310c69 |
* index in this implementation, and we call it the dense portion of the
|
|
Packit Service |
310c69 |
* index.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param masterIndex The master index
|
|
Packit Service |
310c69 |
* @param dense Stats for the dense portion of the index
|
|
Packit Service |
310c69 |
* @param sparse Stats for the sparse portion of the index
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static void getMasterIndexStats_006(const MasterIndex *masterIndex,
|
|
Packit Service |
310c69 |
MasterIndexStats *dense,
|
|
Packit Service |
310c69 |
MasterIndexStats *sparse)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
const MasterIndex6 *mi6 = const_container_of(masterIndex, MasterIndex6,
|
|
Packit Service |
310c69 |
common);
|
|
Packit Service |
310c69 |
MasterIndexStats dummyStats;
|
|
Packit Service |
310c69 |
getMasterIndexStats(mi6->miNonHook, dense, &dummyStats);
|
|
Packit Service |
310c69 |
getMasterIndexStats(mi6->miHook, sparse, &dummyStats);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/***********************************************************************/
|
|
Packit Service |
310c69 |
typedef struct {
|
|
Packit Service |
310c69 |
Configuration hookConfig; // Describe the hook part of the index
|
|
Packit Service |
310c69 |
Geometry hookGeometry;
|
|
Packit Service |
310c69 |
Configuration nonHookConfig; // Describe the non-hook part of the index
|
|
Packit Service |
310c69 |
Geometry nonHookGeometry;
|
|
Packit Service |
310c69 |
} SplitConfig;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/***********************************************************************/
|
|
Packit Service |
310c69 |
static int splitConfiguration006(const Configuration *config,
|
|
Packit Service |
310c69 |
SplitConfig *split)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
int result
|
|
Packit Service |
310c69 |
= ASSERT_WITH_ERROR_CODE(config->geometry->sparseChaptersPerVolume != 0,
|
|
Packit Service |
310c69 |
UDS_INVALID_ARGUMENT,
|
|
Packit Service |
310c69 |
"cannot initialize sparse+dense master index"
|
|
Packit Service |
310c69 |
" with no sparse chapters");
|
|
Packit Service |
310c69 |
if (result != UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
return result;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
result = ASSERT_WITH_ERROR_CODE(config->sparseSampleRate != 0,
|
|
Packit Service |
310c69 |
UDS_INVALID_ARGUMENT,
|
|
Packit Service |
310c69 |
"cannot initialize sparse+dense master"
|
|
Packit Service |
310c69 |
" index with a sparse sample rate of %u",
|
|
Packit Service |
310c69 |
config->sparseSampleRate);
|
|
Packit Service |
310c69 |
if (result != UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
return result;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
// Start with copies of the base configuration
|
|
Packit Service |
310c69 |
split->hookConfig = *config;
|
|
Packit Service |
310c69 |
split->hookGeometry = *config->geometry;
|
|
Packit Service |
310c69 |
split->hookConfig.geometry = &split->hookGeometry;
|
|
Packit Service |
310c69 |
split->nonHookConfig = *config;
|
|
Packit Service |
310c69 |
split->nonHookGeometry = *config->geometry;
|
|
Packit Service |
310c69 |
split->nonHookConfig.geometry = &split->nonHookGeometry;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
uint64_t sampleRate = config->sparseSampleRate;
|
|
Packit Service |
310c69 |
uint64_t numChapters = config->geometry->chaptersPerVolume;
|
|
Packit Service |
310c69 |
uint64_t numSparseChapters = config->geometry->sparseChaptersPerVolume;
|
|
Packit Service |
310c69 |
uint64_t numDenseChapters = numChapters - numSparseChapters;
|
|
Packit Service |
310c69 |
uint64_t sampleRecords = config->geometry->recordsPerChapter / sampleRate;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
// Adjust the number of records indexed for each chapter
|
|
Packit Service |
310c69 |
split->hookGeometry.recordsPerChapter = sampleRecords;
|
|
Packit Service |
310c69 |
split->nonHookGeometry.recordsPerChapter -= sampleRecords;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
// Adjust the number of chapters indexed
|
|
Packit Service |
310c69 |
split->hookGeometry.sparseChaptersPerVolume = 0;
|
|
Packit Service |
310c69 |
split->nonHookGeometry.sparseChaptersPerVolume = 0;
|
|
Packit Service |
310c69 |
split->nonHookGeometry.chaptersPerVolume = numDenseChapters;
|
|
Packit Service |
310c69 |
return UDS_SUCCESS;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/***********************************************************************/
|
|
Packit Service |
310c69 |
int computeMasterIndexSaveBytes006(const Configuration *config,
|
|
Packit Service |
310c69 |
size_t *numBytes)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
SplitConfig split;
|
|
Packit Service |
310c69 |
int result = splitConfiguration006(config, &split);
|
|
Packit Service |
310c69 |
if (result != UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
return result;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
size_t hookBytes, nonHookBytes;
|
|
Packit Service |
310c69 |
result = computeMasterIndexSaveBytes005(&split.hookConfig, &hookBytes);
|
|
Packit Service |
310c69 |
if (result != UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
return result;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
result = computeMasterIndexSaveBytes005(&split.nonHookConfig, &nonHookBytes);
|
|
Packit Service |
310c69 |
if (result != UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
return result;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
// Saving a MasterIndex006 needs a header plus the hook index plus the
|
|
Packit Service |
310c69 |
// non-hook index
|
|
Packit Service |
310c69 |
*numBytes = sizeof(struct mi006_data) + hookBytes + nonHookBytes;
|
|
Packit Service |
310c69 |
return UDS_SUCCESS;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/***********************************************************************/
|
|
Packit Service |
310c69 |
int makeMasterIndex006(const Configuration *config, unsigned int numZones,
|
|
Packit Service |
310c69 |
uint64_t volumeNonce, MasterIndex **masterIndex)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
SplitConfig split;
|
|
Packit Service |
310c69 |
int result = splitConfiguration006(config, &split);
|
|
Packit Service |
310c69 |
if (result != UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
return result;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
MasterIndex6 *mi6;
|
|
Packit Service |
310c69 |
result = ALLOCATE(1, MasterIndex6, "master index", &mi6;;
|
|
Packit Service |
310c69 |
if (result != UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
return result;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
mi6->common.abortRestoringMasterIndex = abortRestoringMasterIndex_006;
|
|
Packit Service |
310c69 |
mi6->common.abortSavingMasterIndex = abortSavingMasterIndex_006;
|
|
Packit Service |
310c69 |
mi6->common.finishSavingMasterIndex = finishSavingMasterIndex_006;
|
|
Packit Service |
310c69 |
mi6->common.freeMasterIndex = freeMasterIndex_006;
|
|
Packit Service |
310c69 |
mi6->common.getMasterIndexMemoryUsed = getMasterIndexMemoryUsed_006;
|
|
Packit Service |
310c69 |
mi6->common.getMasterIndexRecord = getMasterIndexRecord_006;
|
|
Packit Service |
310c69 |
mi6->common.getMasterIndexStats = getMasterIndexStats_006;
|
|
Packit Service |
310c69 |
mi6->common.getMasterIndexZone = getMasterIndexZone_006;
|
|
Packit Service |
310c69 |
mi6->common.isMasterIndexSample = isMasterIndexSample_006;
|
|
Packit Service |
310c69 |
mi6->common.isRestoringMasterIndexDone = isRestoringMasterIndexDone_006;
|
|
Packit Service |
310c69 |
mi6->common.isSavingMasterIndexDone = isSavingMasterIndexDone_006;
|
|
Packit Service |
310c69 |
mi6->common.lookupMasterIndexName = lookupMasterIndexName_006;
|
|
Packit Service |
310c69 |
mi6->common.lookupMasterIndexSampledName = lookupMasterIndexSampledName_006;
|
|
Packit Service |
310c69 |
mi6->common.restoreDeltaListToMasterIndex = restoreDeltaListToMasterIndex_006;
|
|
Packit Service |
310c69 |
mi6->common.setMasterIndexOpenChapter = setMasterIndexOpenChapter_006;
|
|
Packit Service |
310c69 |
mi6->common.setMasterIndexTag = setMasterIndexTag_006;
|
|
Packit Service |
310c69 |
mi6->common.setMasterIndexZoneOpenChapter = setMasterIndexZoneOpenChapter_006;
|
|
Packit Service |
310c69 |
mi6->common.startRestoringMasterIndex = startRestoringMasterIndex_006;
|
|
Packit Service |
310c69 |
mi6->common.startSavingMasterIndex = startSavingMasterIndex_006;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
mi6->numZones = numZones;
|
|
Packit Service |
310c69 |
mi6->sparseSampleRate = config->sparseSampleRate;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
result = ALLOCATE(numZones, MasterIndexZone, "master index zones",
|
|
Packit Service |
310c69 |
&mi6->masterZones);
|
|
Packit Service |
310c69 |
unsigned int zone;
|
|
Packit Service |
310c69 |
for (zone = 0; zone < numZones; zone++) {
|
|
Packit Service |
310c69 |
if (result == UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
result = initMutex(&mi6->masterZones[zone].hookMutex);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
if (result != UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
freeMasterIndex_006(&mi6->common);
|
|
Packit Service |
310c69 |
return result;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
result = makeMasterIndex005(&split.nonHookConfig, numZones, volumeNonce,
|
|
Packit Service |
310c69 |
&mi6->miNonHook);
|
|
Packit Service |
310c69 |
if (result != UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
freeMasterIndex_006(&mi6->common);
|
|
Packit Service |
310c69 |
return logErrorWithStringError(result,
|
|
Packit Service |
310c69 |
"Error creating non hook master index");
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
setMasterIndexTag(mi6->miNonHook, 'd');
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
result = makeMasterIndex005(&split.hookConfig, numZones, volumeNonce,
|
|
Packit Service |
310c69 |
&mi6->miHook);
|
|
Packit Service |
310c69 |
if (result != UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
freeMasterIndex_006(&mi6->common);
|
|
Packit Service |
310c69 |
return logErrorWithStringError(result,
|
|
Packit Service |
310c69 |
"Error creating hook master index");
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
setMasterIndexTag(mi6->miHook, 's');
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
*masterIndex = &mi6->common;
|
|
Packit Service |
310c69 |
return UDS_SUCCESS;
|
|
Packit Service |
310c69 |
}
|