1// Licensed to the .NET Foundation under one or more agreements.
2// The .NET Foundation licenses this file to you under the MIT license.
3// See the LICENSE file in the project root for more information.
4//*****************************************************************************
5// RecordPool.h -- header file for record heaps.
6//
7
8//
9//*****************************************************************************
10#ifndef _RECORDPOOL_H_
11#define _RECORDPOOL_H_
12
13#if _MSC_VER >= 1100
14#pragma once
15#endif
16
17#include <stgpool.h>
18
19//*****************************************************************************
20// This Record pool class collects user Records into a big consecutive heap.
21// The list of Records is kept in memory while adding, and
22// finally flushed to a stream at the caller's request.
23//*****************************************************************************
24class RecordPool : public StgPool
25{
26 friend class VerifyLayoutsMD;
27
28 using StgPool::InitNew;
29 using StgPool::InitOnMem;
30
31public:
32 RecordPool() :
33 StgPool(1024, 1)
34 { }
35
36//*****************************************************************************
37// Init the pool for use. This is called for the create empty case.
38//*****************************************************************************
39 __checkReturn
40 HRESULT InitNew(
41 UINT32 cbRec, // Record size.
42 UINT32 cRecsInit); // Initial guess of count of record.
43
44//*****************************************************************************
45// Load a Record heap from persisted memory. If a copy of the data is made
46// (so that it may be updated), then a new hash table is generated which can
47// be used to elminate duplicates with new Records.
48//*****************************************************************************
49 __checkReturn
50 HRESULT InitOnMem(
51 ULONG cbRec, // Record size.
52 void *pData, // Predefined data.
53 ULONG iSize, // Size of data.
54 BOOL fReadOnly); // true if append is forbidden.
55
56//*****************************************************************************
57// Allocate memory if we don't have any, or grow what we have. If successful,
58// then at least iRequired bytes will be allocated.
59//*****************************************************************************
60 bool Grow( // true if successful.
61 ULONG iRequired); // Min required bytes to allocate.
62
63//*****************************************************************************
64// The Record will be added to the pool. The index of the Record in the pool
65// is returned in *piIndex. If the Record is already in the pool, then the
66// index will be to the existing copy of the Record.
67//*****************************************************************************
68 HRESULT AddRecord(
69 BYTE **ppRecord,
70 UINT32 *pnIndex); // Return 1-based index of Record here.
71
72//*****************************************************************************
73// Insert a Record into the pool. The index of the Record before which to
74// insert is specified. Shifts all records down. Return a pointer to the
75// new record.
76//*****************************************************************************
77 HRESULT InsertRecord(
78 UINT32 nIndex, // [IN] Insert record before this.
79 BYTE **ppRecord);
80
81//*****************************************************************************
82// Return a pointer to a Record given an index previously handed out by
83// AddRecord or FindRecord.
84//*****************************************************************************
85 __checkReturn
86 virtual HRESULT GetRecord(
87 UINT32 nIndex, // 1-based index of Record in pool.
88 BYTE **ppRecord);
89
90//*****************************************************************************
91// Given a pointer to a record, determine the index corresponding to the
92// record.
93//*****************************************************************************
94 virtual ULONG GetIndexForRecord( // 1-based index of Record in pool.
95 const void *pRecord); // Pointer to Record in pool.
96
97//*****************************************************************************
98// Given a purported pointer to a record, determine if the pointer is valid.
99//*****************************************************************************
100 virtual int IsValidPointerForRecord( // true or false.
101 const void *pRecord); // Pointer to Record in pool.
102
103//*****************************************************************************
104// How many objects are there in the pool? If the count is 0, you don't need
105// to persist anything at all to disk.
106//*****************************************************************************
107 UINT32 Count()
108 { return GetNextOffset() / m_cbRec; }
109
110//*****************************************************************************
111// Indicate if heap is empty. This has to be based on the size of the data
112// we are keeping. If you open in r/o mode on memory, there is no hash
113// table.
114//*****************************************************************************
115 virtual int IsEmpty() // true if empty.
116 { return (GetNextOffset() == 0); }
117
118//*****************************************************************************
119// Is the index valid for the Record?
120//*****************************************************************************
121 virtual int IsValidCookie(ULONG ulCookie)
122 { return (ulCookie == 0 || IsValidOffset((ulCookie-1) * m_cbRec)); }
123
124//*****************************************************************************
125// Return the size of the heap.
126//*****************************************************************************
127 ULONG GetNextIndex()
128 { return (GetNextOffset() / m_cbRec); }
129
130//*****************************************************************************
131// Replace the contents of this pool with those from another pool. The other
132// pool loses ownership of the memory.
133//*****************************************************************************
134 __checkReturn
135 HRESULT ReplaceContents(
136 RecordPool *pOther); // The other record pool.
137
138//*****************************************************************************
139// Return the first record in a pool, and set up a context for fast
140// iterating through the pool. Note that this scheme does pretty minimal
141// error checking.
142//*****************************************************************************
143 void *GetFirstRecord( // Pointer to Record in pool.
144 void **pContext); // Store context here.
145
146//*****************************************************************************
147// Given a pointer to a record, return a pointer to the next record.
148// Note that this scheme does pretty minimal error checking. In particular,
149// this will let the caller walk off of the end of valid data in the last
150// segment.
151//*****************************************************************************
152 void *GetNextRecord( // Pointer to Record in pool.
153 void *pRecord, // Current record.
154 void **pContext); // Stored context here.
155
156private:
157 UINT32 m_cbRec; // How large is each record?
158
159}; // class RecordPool
160
161#endif // _RECORDPOOL_H_
162