Blame source/uds/masterIndexOps.c

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
}