diff options
Diffstat (limited to 'src/md/inc/recordpool.h')
-rw-r--r-- | src/md/inc/recordpool.h | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/src/md/inc/recordpool.h b/src/md/inc/recordpool.h new file mode 100644 index 0000000000..36bd67a656 --- /dev/null +++ b/src/md/inc/recordpool.h @@ -0,0 +1,161 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. +//***************************************************************************** +// RecordPool.h -- header file for record heaps. +// + +// +//***************************************************************************** +#ifndef _RECORDPOOL_H_ +#define _RECORDPOOL_H_ + +#if _MSC_VER >= 1100 +#pragma once +#endif + +#include <stgpool.h> + +//***************************************************************************** +// This Record pool class collects user Records into a big consecutive heap. +// The list of Records is kept in memory while adding, and +// finally flushed to a stream at the caller's request. +//***************************************************************************** +class RecordPool : public StgPool +{ + friend class VerifyLayoutsMD; + + using StgPool::InitNew; + using StgPool::InitOnMem; + +public: + RecordPool() : + StgPool(1024, 1) + { } + +//***************************************************************************** +// Init the pool for use. This is called for the create empty case. +//***************************************************************************** + __checkReturn + HRESULT InitNew( + UINT32 cbRec, // Record size. + UINT32 cRecsInit); // Initial guess of count of record. + +//***************************************************************************** +// Load a Record heap from persisted memory. If a copy of the data is made +// (so that it may be updated), then a new hash table is generated which can +// be used to elminate duplicates with new Records. +//***************************************************************************** + __checkReturn + HRESULT InitOnMem( + ULONG cbRec, // Record size. + void *pData, // Predefined data. + ULONG iSize, // Size of data. + BOOL fReadOnly); // true if append is forbidden. + +//***************************************************************************** +// Allocate memory if we don't have any, or grow what we have. If successful, +// then at least iRequired bytes will be allocated. +//***************************************************************************** + bool Grow( // true if successful. + ULONG iRequired); // Min required bytes to allocate. + +//***************************************************************************** +// The Record will be added to the pool. The index of the Record in the pool +// is returned in *piIndex. If the Record is already in the pool, then the +// index will be to the existing copy of the Record. +//***************************************************************************** + HRESULT AddRecord( + BYTE **ppRecord, + UINT32 *pnIndex); // Return 1-based index of Record here. + +//***************************************************************************** +// Insert a Record into the pool. The index of the Record before which to +// insert is specified. Shifts all records down. Return a pointer to the +// new record. +//***************************************************************************** + HRESULT InsertRecord( + UINT32 nIndex, // [IN] Insert record before this. + BYTE **ppRecord); + +//***************************************************************************** +// Return a pointer to a Record given an index previously handed out by +// AddRecord or FindRecord. +//***************************************************************************** + __checkReturn + virtual HRESULT GetRecord( + UINT32 nIndex, // 1-based index of Record in pool. + BYTE **ppRecord); + +//***************************************************************************** +// Given a pointer to a record, determine the index corresponding to the +// record. +//***************************************************************************** + virtual ULONG GetIndexForRecord( // 1-based index of Record in pool. + const void *pRecord); // Pointer to Record in pool. + +//***************************************************************************** +// Given a purported pointer to a record, determine if the pointer is valid. +//***************************************************************************** + virtual int IsValidPointerForRecord( // true or false. + const void *pRecord); // Pointer to Record in pool. + +//***************************************************************************** +// How many objects are there in the pool? If the count is 0, you don't need +// to persist anything at all to disk. +//***************************************************************************** + UINT32 Count() + { return GetNextOffset() / m_cbRec; } + +//***************************************************************************** +// Indicate if heap is empty. This has to be based on the size of the data +// we are keeping. If you open in r/o mode on memory, there is no hash +// table. +//***************************************************************************** + virtual int IsEmpty() // true if empty. + { return (GetNextOffset() == 0); } + +//***************************************************************************** +// Is the index valid for the Record? +//***************************************************************************** + virtual int IsValidCookie(ULONG ulCookie) + { return (ulCookie == 0 || IsValidOffset((ulCookie-1) * m_cbRec)); } + +//***************************************************************************** +// Return the size of the heap. +//***************************************************************************** + ULONG GetNextIndex() + { return (GetNextOffset() / m_cbRec); } + +//***************************************************************************** +// Replace the contents of this pool with those from another pool. The other +// pool loses ownership of the memory. +//***************************************************************************** + __checkReturn + HRESULT ReplaceContents( + RecordPool *pOther); // The other record pool. + +//***************************************************************************** +// Return the first record in a pool, and set up a context for fast +// iterating through the pool. Note that this scheme does pretty minimal +// error checking. +//***************************************************************************** + void *GetFirstRecord( // Pointer to Record in pool. + void **pContext); // Store context here. + +//***************************************************************************** +// Given a pointer to a record, return a pointer to the next record. +// Note that this scheme does pretty minimal error checking. In particular, +// this will let the caller walk off of the end of valid data in the last +// segment. +//***************************************************************************** + void *GetNextRecord( // Pointer to Record in pool. + void *pRecord, // Current record. + void **pContext); // Stored context here. + +private: + UINT32 m_cbRec; // How large is each record? + +}; // class RecordPool + +#endif // _RECORDPOOL_H_ |