// 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 //***************************************************************************** // 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_