summaryrefslogtreecommitdiff
path: root/src/md/inc/recordpool.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/md/inc/recordpool.h')
-rw-r--r--src/md/inc/recordpool.h161
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_