|
Packit |
b55c50 |
/*
|
|
Packit |
b55c50 |
* Copyright (c) 2020 Red Hat, Inc.
|
|
Packit |
b55c50 |
*
|
|
Packit |
b55c50 |
* This program is free software; you can redistribute it and/or
|
|
Packit |
b55c50 |
* modify it under the terms of the GNU General Public License
|
|
Packit |
b55c50 |
* as published by the Free Software Foundation; either version 2
|
|
Packit |
b55c50 |
* of the License, or (at your option) any later version.
|
|
Packit |
b55c50 |
*
|
|
Packit |
b55c50 |
* This program is distributed in the hope that it will be useful,
|
|
Packit |
b55c50 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
b55c50 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit |
b55c50 |
* GNU General Public License for more details.
|
|
Packit |
b55c50 |
*
|
|
Packit |
b55c50 |
* You should have received a copy of the GNU General Public License
|
|
Packit |
b55c50 |
* along with this program; if not, write to the Free Software
|
|
Packit |
b55c50 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
Packit |
b55c50 |
* 02110-1301, USA.
|
|
Packit |
b55c50 |
*
|
|
Packit |
b55c50 |
* $Id: //eng/uds-releases/jasper/src/uds/geometry.h#3 $
|
|
Packit |
b55c50 |
*/
|
|
Packit |
b55c50 |
|
|
Packit |
b55c50 |
#ifndef GEOMETRY_H
|
|
Packit |
b55c50 |
#define GEOMETRY_H 1
|
|
Packit |
b55c50 |
|
|
Packit |
b55c50 |
#include "compiler.h"
|
|
Packit |
b55c50 |
#include "typeDefs.h"
|
|
Packit |
b55c50 |
#include "uds.h"
|
|
Packit |
b55c50 |
#include "uds-block.h"
|
|
Packit |
b55c50 |
|
|
Packit |
b55c50 |
/**
|
|
Packit |
b55c50 |
* Geometry defines constants and a record that parameterize the layout of an
|
|
Packit |
b55c50 |
* Albireo index volume.
|
|
Packit |
b55c50 |
*
|
|
Packit |
b55c50 |
* An index volume is divided into a fixed number of fixed-size
|
|
Packit |
b55c50 |
* chapters, each consisting of a fixed number of fixed-size
|
|
Packit |
b55c50 |
* pages. The volume layout is defined by two assumptions and four
|
|
Packit |
b55c50 |
* parameters. The assumptions (constants) are that index records are
|
|
Packit |
b55c50 |
* 64 bytes (32-byte block name plus 32-byte metadata) and that open
|
|
Packit |
b55c50 |
* chapter index hash slots are one byte long. The four parameters are
|
|
Packit |
b55c50 |
* the number of bytes in a page, the number of chapters in a volume,
|
|
Packit |
b55c50 |
* the number of record pages in a chapter, and the number of chapters
|
|
Packit |
b55c50 |
* that are sparse. From these parameters, we derive the rest of the
|
|
Packit |
b55c50 |
* layout and derived properties, ranging from the number of pages in
|
|
Packit |
b55c50 |
* a chapter to the number of records in the volume.
|
|
Packit |
b55c50 |
*
|
|
Packit |
b55c50 |
* The default geometry is 64 KByte pages, 1024 chapters, 256
|
|
Packit |
b55c50 |
* record pages in a chapter, and zero sparse chapters. This will
|
|
Packit |
b55c50 |
* allow us to store 2^28 entries (indexing 1TB of 4K blocks) in an
|
|
Packit |
b55c50 |
* approximately 16.5 MByte volume using fourteen index pages in each
|
|
Packit |
b55c50 |
* chapter.
|
|
Packit |
b55c50 |
**/
|
|
Packit |
b55c50 |
typedef struct geometry {
|
|
Packit |
b55c50 |
/** Length of a page in a chapter, in bytes */
|
|
Packit |
b55c50 |
size_t bytesPerPage;
|
|
Packit |
b55c50 |
/** Number of record pages in a chapter */
|
|
Packit |
b55c50 |
unsigned int recordPagesPerChapter;
|
|
Packit |
b55c50 |
/** Number of (total) chapters in a volume */
|
|
Packit |
b55c50 |
unsigned int chaptersPerVolume;
|
|
Packit |
b55c50 |
/** Number of sparsely-indexed chapters in a volume */
|
|
Packit |
b55c50 |
unsigned int sparseChaptersPerVolume;
|
|
Packit |
b55c50 |
/** Number of bits used to determine delta list numbers */
|
|
Packit |
b55c50 |
unsigned int chapterDeltaListBits;
|
|
Packit |
b55c50 |
|
|
Packit |
b55c50 |
// These are derived properties, expressed as fields for convenience.
|
|
Packit |
b55c50 |
/** Total number of pages in a volume, excluding header */
|
|
Packit |
b55c50 |
unsigned int pagesPerVolume;
|
|
Packit |
b55c50 |
/** Total number of header pages per volume */
|
|
Packit |
b55c50 |
unsigned int headerPagesPerVolume;
|
|
Packit |
b55c50 |
/** Total number of bytes in a volume, including header */
|
|
Packit |
b55c50 |
size_t bytesPerVolume;
|
|
Packit |
b55c50 |
/** Total number of bytes in a chapter */
|
|
Packit |
b55c50 |
size_t bytesPerChapter;
|
|
Packit |
b55c50 |
/** Number of pages in a chapter */
|
|
Packit |
b55c50 |
unsigned int pagesPerChapter;
|
|
Packit |
b55c50 |
/** Number of index pages in a chapter index */
|
|
Packit |
b55c50 |
unsigned int indexPagesPerChapter;
|
|
Packit |
b55c50 |
/** The minimum ratio of hash slots to records in an open chapter */
|
|
Packit |
b55c50 |
unsigned int openChapterLoadRatio;
|
|
Packit |
b55c50 |
/** Number of records that fit on a page */
|
|
Packit |
b55c50 |
unsigned int recordsPerPage;
|
|
Packit |
b55c50 |
/** Number of records that fit in a chapter */
|
|
Packit |
b55c50 |
unsigned int recordsPerChapter;
|
|
Packit |
b55c50 |
/** Number of records that fit in a volume */
|
|
Packit |
b55c50 |
uint64_t recordsPerVolume;
|
|
Packit |
b55c50 |
/** Number of deltaLists per chapter index */
|
|
Packit |
b55c50 |
unsigned int deltaListsPerChapter;
|
|
Packit |
b55c50 |
/** Mean delta in chapter indexes */
|
|
Packit |
b55c50 |
unsigned int chapterMeanDelta;
|
|
Packit |
b55c50 |
/** Number of bits needed for record page numbers */
|
|
Packit |
b55c50 |
unsigned int chapterPayloadBits;
|
|
Packit |
b55c50 |
/** Number of bits used to compute addresses for chapter delta lists */
|
|
Packit |
b55c50 |
unsigned int chapterAddressBits;
|
|
Packit |
b55c50 |
/** Number of densely-indexed chapters in a volume */
|
|
Packit |
b55c50 |
unsigned int denseChaptersPerVolume;
|
|
Packit |
b55c50 |
} Geometry;
|
|
Packit |
b55c50 |
|
|
Packit |
b55c50 |
enum {
|
|
Packit |
b55c50 |
/* The number of bytes in a record (name + metadata) */
|
|
Packit |
b55c50 |
BYTES_PER_RECORD = (UDS_CHUNK_NAME_SIZE + UDS_MAX_BLOCK_DATA_SIZE),
|
|
Packit |
b55c50 |
|
|
Packit |
b55c50 |
/* The default length of a page in a chapter, in bytes */
|
|
Packit |
b55c50 |
DEFAULT_BYTES_PER_PAGE = 1024 * BYTES_PER_RECORD,
|
|
Packit |
b55c50 |
|
|
Packit |
b55c50 |
/* The default maximum number of records per page */
|
|
Packit |
b55c50 |
DEFAULT_RECORDS_PER_PAGE = DEFAULT_BYTES_PER_PAGE / BYTES_PER_RECORD,
|
|
Packit |
b55c50 |
|
|
Packit |
b55c50 |
/** The default number of record pages in a chapter */
|
|
Packit |
b55c50 |
DEFAULT_RECORD_PAGES_PER_CHAPTER = 256,
|
|
Packit |
b55c50 |
|
|
Packit |
b55c50 |
/** The default number of record pages in a chapter for a small index */
|
|
Packit |
b55c50 |
SMALL_RECORD_PAGES_PER_CHAPTER = 64,
|
|
Packit |
b55c50 |
|
|
Packit |
b55c50 |
/** The default number of chapters in a volume */
|
|
Packit |
b55c50 |
DEFAULT_CHAPTERS_PER_VOLUME = 1024,
|
|
Packit |
b55c50 |
|
|
Packit |
b55c50 |
/** The default number of sparsely-indexed chapters in a volume */
|
|
Packit |
b55c50 |
DEFAULT_SPARSE_CHAPTERS_PER_VOLUME = 0,
|
|
Packit |
b55c50 |
|
|
Packit |
b55c50 |
/** The log2 of the default mean delta */
|
|
Packit |
b55c50 |
DEFAULT_CHAPTER_MEAN_DELTA_BITS = 16,
|
|
Packit |
b55c50 |
|
|
Packit |
b55c50 |
/** The log2 of the number of delta lists in a large chapter */
|
|
Packit |
b55c50 |
DEFAULT_CHAPTER_DELTA_LIST_BITS = 12,
|
|
Packit |
b55c50 |
|
|
Packit |
b55c50 |
/** The log2 of the number of delta lists in a small chapter */
|
|
Packit |
b55c50 |
SMALL_CHAPTER_DELTA_LIST_BITS = 10,
|
|
Packit |
b55c50 |
|
|
Packit |
b55c50 |
/** The default min ratio of slots to records in an open chapter */
|
|
Packit |
b55c50 |
DEFAULT_OPEN_CHAPTER_LOAD_RATIO = 2,
|
|
Packit |
b55c50 |
|
|
Packit |
b55c50 |
/** Checkpoint every n chapters written. Default is to not checkpoint */
|
|
Packit |
b55c50 |
DEFAULT_CHECKPOINT_FREQUENCY = 0
|
|
Packit |
b55c50 |
};
|
|
Packit |
b55c50 |
|
|
Packit |
b55c50 |
/**
|
|
Packit |
b55c50 |
* Allocate and initialize all fields of a volume geometry using the
|
|
Packit |
b55c50 |
* specified layout parameters.
|
|
Packit |
b55c50 |
*
|
|
Packit |
b55c50 |
* @param bytesPerPage The length of a page in a chapter, in bytes
|
|
Packit |
b55c50 |
* @param recordPagesPerChapter The number of pages in a chapter
|
|
Packit |
b55c50 |
* @param chaptersPerVolume The number of chapters in a volume
|
|
Packit |
b55c50 |
* @param sparseChaptersPerVolume The number of sparse chapters in a volume
|
|
Packit |
b55c50 |
* @param geometryPtr A pointer to hold the new geometry
|
|
Packit |
b55c50 |
*
|
|
Packit |
b55c50 |
* @return UDS_SUCCESS or an error code
|
|
Packit |
b55c50 |
**/
|
|
Packit |
b55c50 |
int makeGeometry(size_t bytesPerPage,
|
|
Packit |
b55c50 |
unsigned int recordPagesPerChapter,
|
|
Packit |
b55c50 |
unsigned int chaptersPerVolume,
|
|
Packit |
b55c50 |
unsigned int sparseChaptersPerVolume,
|
|
Packit |
b55c50 |
Geometry **geometryPtr)
|
|
Packit |
b55c50 |
__attribute__((warn_unused_result));
|
|
Packit |
b55c50 |
|
|
Packit |
b55c50 |
/**
|
|
Packit |
b55c50 |
* Allocate a new geometry and initialize it with the same parameters as an
|
|
Packit |
b55c50 |
* existing geometry.
|
|
Packit |
b55c50 |
*
|
|
Packit |
b55c50 |
* @param source The geometry record to copy
|
|
Packit |
b55c50 |
* @param geometryPtr A pointer to hold the new geometry
|
|
Packit |
b55c50 |
*
|
|
Packit |
b55c50 |
* @return UDS_SUCCESS or an error code
|
|
Packit |
b55c50 |
**/
|
|
Packit |
b55c50 |
int copyGeometry(Geometry *source,
|
|
Packit |
b55c50 |
Geometry **geometryPtr)
|
|
Packit |
b55c50 |
__attribute__((warn_unused_result));
|
|
Packit |
b55c50 |
|
|
Packit |
b55c50 |
/**
|
|
Packit |
b55c50 |
* Clean up a geometry and its memory.
|
|
Packit |
b55c50 |
*
|
|
Packit |
b55c50 |
* @param geometry The geometry record to free
|
|
Packit |
b55c50 |
**/
|
|
Packit |
b55c50 |
void freeGeometry(Geometry *geometry);
|
|
Packit |
b55c50 |
|
|
Packit |
b55c50 |
/**
|
|
Packit |
b55c50 |
* Map a virtual chapter number to a physical chapter number
|
|
Packit |
b55c50 |
*
|
|
Packit |
b55c50 |
* @param geometry The geometry
|
|
Packit |
b55c50 |
* @param virtualChapter The virtual chapter number
|
|
Packit |
b55c50 |
*
|
|
Packit |
b55c50 |
* @return the corresponding physical chapter number
|
|
Packit |
b55c50 |
**/
|
|
Packit |
b55c50 |
__attribute__((warn_unused_result))
|
|
Packit |
b55c50 |
static INLINE unsigned int mapToPhysicalChapter(const Geometry *geometry,
|
|
Packit |
b55c50 |
uint64_t virtualChapter)
|
|
Packit |
b55c50 |
{
|
|
Packit |
b55c50 |
return (virtualChapter % geometry->chaptersPerVolume);
|
|
Packit |
b55c50 |
}
|
|
Packit |
b55c50 |
|
|
Packit |
b55c50 |
/**
|
|
Packit |
b55c50 |
* Convert a physical chapter number to its current virtual chapter number.
|
|
Packit |
b55c50 |
*
|
|
Packit |
b55c50 |
* @param geometry The geometry
|
|
Packit |
b55c50 |
* @param newestVirtualChapter The number of the newest virtual chapter
|
|
Packit |
b55c50 |
* @param physicalChapter The physical chapter number to convert
|
|
Packit |
b55c50 |
*
|
|
Packit |
b55c50 |
* @return The current virtual chapter number of the physical chapter
|
|
Packit |
b55c50 |
* in question
|
|
Packit |
b55c50 |
**/
|
|
Packit |
b55c50 |
uint64_t mapToVirtualChapterNumber(Geometry *geometry,
|
|
Packit |
b55c50 |
uint64_t newestVirtualChapter,
|
|
Packit |
b55c50 |
unsigned int physicalChapter);
|
|
Packit |
b55c50 |
|
|
Packit |
b55c50 |
/**
|
|
Packit |
b55c50 |
* Check whether this geometry is for a sparse index.
|
|
Packit |
b55c50 |
*
|
|
Packit |
b55c50 |
* @param geometry The geometry to check
|
|
Packit |
b55c50 |
*
|
|
Packit |
b55c50 |
* @return true if this geometry has sparse chapters
|
|
Packit |
b55c50 |
**/
|
|
Packit |
b55c50 |
__attribute__((warn_unused_result))
|
|
Packit |
b55c50 |
static INLINE bool isSparse(const Geometry *geometry)
|
|
Packit |
b55c50 |
{
|
|
Packit |
b55c50 |
return (geometry->sparseChaptersPerVolume > 0);
|
|
Packit |
b55c50 |
}
|
|
Packit |
b55c50 |
|
|
Packit |
b55c50 |
/**
|
|
Packit |
b55c50 |
* Check whether any sparse chapters have been filled.
|
|
Packit |
b55c50 |
*
|
|
Packit |
b55c50 |
* @param geometry The geometry of the index
|
|
Packit |
b55c50 |
* @param oldestVirtualChapter The number of the oldest chapter in the
|
|
Packit |
b55c50 |
* index
|
|
Packit |
b55c50 |
* @param newestVirtualChapter The number of the newest chapter in the
|
|
Packit |
b55c50 |
* index
|
|
Packit |
b55c50 |
*
|
|
Packit |
b55c50 |
* @return true if the index has filled at least one sparse chapter
|
|
Packit |
b55c50 |
**/
|
|
Packit |
b55c50 |
bool hasSparseChapters(const Geometry *geometry,
|
|
Packit |
b55c50 |
uint64_t oldestVirtualChapter,
|
|
Packit |
b55c50 |
uint64_t newestVirtualChapter)
|
|
Packit |
b55c50 |
__attribute__((warn_unused_result));
|
|
Packit |
b55c50 |
|
|
Packit |
b55c50 |
/**
|
|
Packit |
b55c50 |
* Check whether a chapter is sparse or dense.
|
|
Packit |
b55c50 |
*
|
|
Packit |
b55c50 |
* @param geometry The geometry of the index containing the chapter
|
|
Packit |
b55c50 |
* @param oldestVirtualChapter The number of the oldest chapter in the index
|
|
Packit |
b55c50 |
* @param newestVirtualChapter The number of the newest chapter in the index
|
|
Packit |
b55c50 |
* @param virtualChapterNumber The number of the chapter to check
|
|
Packit |
b55c50 |
*
|
|
Packit |
b55c50 |
* @return true if the chapter is sparse
|
|
Packit |
b55c50 |
**/
|
|
Packit |
b55c50 |
bool isChapterSparse(const Geometry *geometry,
|
|
Packit |
b55c50 |
uint64_t oldestVirtualChapter,
|
|
Packit |
b55c50 |
uint64_t newestVirtualChapter,
|
|
Packit |
b55c50 |
uint64_t virtualChapterNumber)
|
|
Packit |
b55c50 |
__attribute__((warn_unused_result));
|
|
Packit |
b55c50 |
|
|
Packit |
b55c50 |
/**
|
|
Packit |
b55c50 |
* Check whether two virtual chapter numbers correspond to the same
|
|
Packit |
b55c50 |
* physical chapter.
|
|
Packit |
b55c50 |
*
|
|
Packit |
b55c50 |
* @param geometry The geometry of the index
|
|
Packit |
b55c50 |
* @param chapter1 The first chapter to compare
|
|
Packit |
b55c50 |
* @param chapter2 The second chapter to compare
|
|
Packit |
b55c50 |
*
|
|
Packit |
b55c50 |
* @return true if both chapters correspond to the same
|
|
Packit |
b55c50 |
* physical chapter
|
|
Packit |
b55c50 |
**/
|
|
Packit |
b55c50 |
bool areSamePhysicalChapter(const Geometry *geometry,
|
|
Packit |
b55c50 |
uint64_t chapter1,
|
|
Packit |
b55c50 |
uint64_t chapter2)
|
|
Packit |
b55c50 |
__attribute__((warn_unused_result));
|
|
Packit |
b55c50 |
|
|
Packit |
b55c50 |
#endif /* GEOMETRY_H */
|