|
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/vdo-releases/aluminum/src/c++/vdo/base/packerInternals.h#4 $
|
|
Packit Service |
310c69 |
*/
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
#ifndef PACKER_INTERNALS_H
|
|
Packit Service |
310c69 |
#define PACKER_INTERNALS_H
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
#include "packer.h"
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
#include "atomic.h"
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
#include "adminState.h"
|
|
Packit Service |
310c69 |
#include "compressedBlock.h"
|
|
Packit Service |
310c69 |
#include "header.h"
|
|
Packit Service |
310c69 |
#include "types.h"
|
|
Packit Service |
310c69 |
#include "waitQueue.h"
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Each InputBin holds an incomplete batch of DataVIOs that only partially fill
|
|
Packit Service |
310c69 |
* a compressed block. The InputBins are kept in a ring sorted by the amount of
|
|
Packit Service |
310c69 |
* unused space so the first bin with enough space to hold a newly-compressed
|
|
Packit Service |
310c69 |
* DataVIO can easily be found. When the bin fills up or is flushed, the
|
|
Packit Service |
310c69 |
* incoming DataVIOs are moved to the Packer's batchedDataVIOs queue, from
|
|
Packit Service |
310c69 |
* which they will eventually be routed to an idle OutputBin.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* There is one special input bin which is used to hold DataVIOs which have
|
|
Packit Service |
310c69 |
* been canceled and removed from their input bin by the packer. These DataVIOs
|
|
Packit Service |
310c69 |
* need to wait for the canceller to rendezvous with them (VDO-2809) and so
|
|
Packit Service |
310c69 |
* they sit in this special bin.
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
struct inputBin {
|
|
Packit Service |
310c69 |
/** List links for Packer.sortedBins */
|
|
Packit Service |
310c69 |
RingNode ring;
|
|
Packit Service |
310c69 |
/** The number of items in the bin */
|
|
Packit Service |
310c69 |
SlotNumber slotsUsed;
|
|
Packit Service |
310c69 |
/** The number of compressed block bytes remaining in the current batch */
|
|
Packit Service |
310c69 |
size_t freeSpace;
|
|
Packit Service |
310c69 |
/** The current partial batch of DataVIOs, waiting for more */
|
|
Packit Service |
310c69 |
DataVIO *incoming[];
|
|
Packit Service |
310c69 |
};
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Each OutputBin allows a single compressed block to be packed and written.
|
|
Packit Service |
310c69 |
* When it is not idle, it holds a batch of DataVIOs that have been packed
|
|
Packit Service |
310c69 |
* into the compressed block, written asynchronously, and are waiting for the
|
|
Packit Service |
310c69 |
* write to complete.
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
typedef struct {
|
|
Packit Service |
310c69 |
/** List links for Packer.outputBins */
|
|
Packit Service |
310c69 |
RingNode ring;
|
|
Packit Service |
310c69 |
/** The storage for encoding the compressed block representation */
|
|
Packit Service |
310c69 |
CompressedBlock *block;
|
|
Packit Service |
310c69 |
/** The AllocatingVIO wrapping the compressed block for writing */
|
|
Packit Service |
310c69 |
AllocatingVIO *writer;
|
|
Packit Service |
310c69 |
/** The number of compression slots used in the compressed block */
|
|
Packit Service |
310c69 |
SlotNumber slotsUsed;
|
|
Packit Service |
310c69 |
/** The DataVIOs packed into the block, waiting for the write to complete */
|
|
Packit Service |
310c69 |
WaitQueue outgoing;
|
|
Packit Service |
310c69 |
} OutputBin;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* A counted array holding a batch of DataVIOs that should be packed into an
|
|
Packit Service |
310c69 |
* output bin.
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
typedef struct {
|
|
Packit Service |
310c69 |
size_t slotsUsed;
|
|
Packit Service |
310c69 |
DataVIO *slots[MAX_COMPRESSION_SLOTS];
|
|
Packit Service |
310c69 |
} OutputBatch;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
struct packer {
|
|
Packit Service |
310c69 |
/** The ID of the packer's callback thread */
|
|
Packit Service |
310c69 |
ThreadID threadID;
|
|
Packit Service |
310c69 |
/** The selector for determining which physical zone to allocate from */
|
|
Packit Service |
310c69 |
AllocationSelector *selector;
|
|
Packit Service |
310c69 |
/** The number of input bins */
|
|
Packit Service |
310c69 |
BlockCount size;
|
|
Packit Service |
310c69 |
/** The block size minus header size */
|
|
Packit Service |
310c69 |
size_t binDataSize;
|
|
Packit Service |
310c69 |
/** The number of compression slots */
|
|
Packit Service |
310c69 |
size_t maxSlots;
|
|
Packit Service |
310c69 |
/** A ring of all InputBins, kept sorted by freeSpace */
|
|
Packit Service |
310c69 |
RingNode inputBins;
|
|
Packit Service |
310c69 |
/** A ring of all OutputBins */
|
|
Packit Service |
310c69 |
RingNode outputBins;
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* A bin to hold DataVIOs which were canceled out of the packer and are
|
|
Packit Service |
310c69 |
* waiting to rendezvous with the canceling DataVIO.
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
InputBin *canceledBin;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/** The current flush generation */
|
|
Packit Service |
310c69 |
SequenceNumber flushGeneration;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/** The administrative state of the packer */
|
|
Packit Service |
310c69 |
AdminState state;
|
|
Packit Service |
310c69 |
/** True when writing batched DataVIOs */
|
|
Packit Service |
310c69 |
bool writingBatches;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
// Atomic counters corresponding to the fields of PackerStatistics:
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/** Number of compressed data items written since startup */
|
|
Packit Service |
310c69 |
Atomic64 fragmentsWritten;
|
|
Packit Service |
310c69 |
/** Number of blocks containing compressed items written since startup */
|
|
Packit Service |
310c69 |
Atomic64 blocksWritten;
|
|
Packit Service |
310c69 |
/** Number of DataVIOs that are pending in the packer */
|
|
Packit Service |
310c69 |
Atomic64 fragmentsPending;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/** Queue of batched DataVIOs waiting to be packed */
|
|
Packit Service |
310c69 |
WaitQueue batchedDataVIOs;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/** The total number of output bins allocated */
|
|
Packit Service |
310c69 |
size_t outputBinCount;
|
|
Packit Service |
310c69 |
/** The number of idle output bins on the stack */
|
|
Packit Service |
310c69 |
size_t idleOutputBinCount;
|
|
Packit Service |
310c69 |
/** The stack of idle output bins (0=bottom) */
|
|
Packit Service |
310c69 |
OutputBin *idleOutputBins[];
|
|
Packit Service |
310c69 |
};
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* This returns the first bin in the freeSpace-sorted list.
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
InputBin *getFullestBin(const Packer *packer);
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* This returns the next bin in the freeSpace-sorted list.
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
InputBin *nextBin(const Packer *packer, InputBin *bin);
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Change the maxiumum number of compression slots the packer will use. The new
|
|
Packit Service |
310c69 |
* number of slots must be less than or equal to MAX_COMPRESSION_SLOTS. Bins
|
|
Packit Service |
310c69 |
* which already have fragments will not be resized until they are next written
|
|
Packit Service |
310c69 |
* out.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param packer The packer
|
|
Packit Service |
310c69 |
* @param slots The new number of slots
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
void resetSlotCount(Packer *packer, CompressedFragmentCount slots);
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Remove a DataVIO from the packer. This method is exposed for testing.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param dataVIO The DataVIO to remove
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
void removeFromPacker(DataVIO *dataVIO);
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
#endif /* PACKER_INTERNALS_H */
|