diff options
Diffstat (limited to 'src/md/tables/table.h')
-rw-r--r-- | src/md/tables/table.h | 244 |
1 files changed, 244 insertions, 0 deletions
diff --git a/src/md/tables/table.h b/src/md/tables/table.h new file mode 100644 index 0000000000..f0b40f285b --- /dev/null +++ b/src/md/tables/table.h @@ -0,0 +1,244 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// +// +// File: Table.h +// + +// +// Class code:MetaData::Table represents a MetaData table. +// +// ====================================================================================== + +#pragma once + +#include "external.h" + +namespace MetaData +{ + +// -------------------------------------------------------------------------------------- +// +// This class represents a read-only MetaData table (a continuous chunk of data). +// +class TableRO +{ + friend class TableRW; + +private: + // + // Private data + // + + BYTE *m_pData; + +public: + // + // Initialization + // + + __checkReturn + inline HRESULT Initialize( + __range(2, UINT32_MAX) UINT32 cbRecordSize, + DataBlob sourceData, + BOOL fCopyData) + { + _ASSERTE(!fCopyData); + _ASSERTE((cbRecordSize == 0) || (sourceData.GetSize() % cbRecordSize == 0)); + m_pData = sourceData.GetDataPointer(); + return S_OK; + } + + // Destroys the table and all its allocated data. Can run on uninitialized table. + inline void Delete() + { + m_pData = NULL; + } + +public: + // + // Getters + // + + __checkReturn + inline HRESULT GetRecord( + UINT32 nRowIndex, + __deref_out_opt BYTE **ppRecord, + UINT32 cbRecordSize, + UINT32 cRecordCount, +#ifdef FEATURE_PREJIT + struct HotTablesDirectory *pHotTablesDirectory, +#endif //FEATURE_PREJIT + UINT32 nTableIndex) + { + if ((nRowIndex == 0) || (nRowIndex > cRecordCount)) + { + Debug_ReportError("Invalid record index."); + *ppRecord = NULL; + return CLDB_E_INDEX_NOTFOUND; + } +#ifdef FEATURE_PREJIT + if ((pHotTablesDirectory != NULL) && (pHotTablesDirectory->m_rgTableHeader_SignedOffset[nTableIndex] != 0)) + { + HRESULT hr = HotTable::GetData( + nRowIndex, + ppRecord, + cbRecordSize, + HotTable::GetTableHeader(pHotTablesDirectory, nTableIndex)); + + if (hr == S_OK) + { + _ASSERTE(memcmp( + *ppRecord, + m_pData + (nRowIndex - 1) * cbRecordSize, + cbRecordSize) == 0); + return S_OK; + } + if (FAILED(hr)) + { + *ppRecord = NULL; + return hr; + } + _ASSERTE(hr == S_FALSE); + } +#endif //FEATURE_PREJIT + *ppRecord = m_pData + (nRowIndex - 1) * cbRecordSize; + return S_OK; + } // TableRO::GetRecord + +}; // class TableRO + +// -------------------------------------------------------------------------------------- +// +// This class represents a read-write MetaData table. +// +class TableRW +{ +private: + // + // Private data + // + + // The storage of table records. + RecordPool m_RecordStorage; + +public: + // + // Initialization + // + + // Initializes (empty) table of record size (cbRecordSize) with new allocated data for cRecordCount + // records. + __checkReturn + inline HRESULT InitializeEmpty_WithRecordCount( + __range(2, UINT32_MAX) UINT32 cbRecordSize, + __range(0, UINT32_MAX) UINT32 cRecordCount + COMMA_INDEBUG_MD( BOOL debug_fIsReadWrite)) + { + return m_RecordStorage.InitNew(cbRecordSize, cRecordCount); + } + + __checkReturn + inline HRESULT Initialize( + __range(2, UINT32_MAX) UINT32 cbRecordSize, + DataBlob sourceData, + BOOL fCopyData) + { + return m_RecordStorage.InitOnMem(cbRecordSize, sourceData.GetDataPointer(), sourceData.GetSize(), !fCopyData); + } + + __checkReturn + inline HRESULT InitializeFromTable( + const TableRO *pSourceTable, + UINT32 cbRecordSize, + UINT32 cRecordCount, + BOOL fCopyData) + { + return m_RecordStorage.InitOnMem(cbRecordSize, pSourceTable->m_pData, cbRecordSize * cRecordCount, !fCopyData); + } + __checkReturn + inline HRESULT InitializeFromTable( + const TableRW *pSourceTable, + BOOL fCopyData) + { + _ASSERTE(fCopyData); + return m_RecordStorage.ReplaceContents(const_cast<RecordPool *>(&pSourceTable->m_RecordStorage)); + } + + // Destroys the table and all its allocated data. Can run on uninitialized table. + inline void Delete() + { + return m_RecordStorage.Uninit(); + } + +public: + // + // Getters + // + + inline UINT32 GetRecordCount() const + { + return const_cast<RecordPool &>(m_RecordStorage).Count(); + } + inline HRESULT GetRecordsDataSize(UINT32 *pcbSize) const + { + return m_RecordStorage.GetSaveSize(pcbSize); + } + + __checkReturn + inline HRESULT GetRecord( + UINT32 nIndex, + __deref_out_opt BYTE **ppRecord) + { + return m_RecordStorage.GetRecord(nIndex, ppRecord); + } + + __checkReturn + inline HRESULT SaveToStream( + IStream *pStream) const + { + return const_cast<RecordPool &>(m_RecordStorage).PersistToStream(pStream); + } + +public: + // + // Setters + // + + __checkReturn + inline HRESULT AddRecord( + __out_bcount(m_cbRecordSize) BYTE **ppbRecord, + __out UINT32 *pnIndex) + { + return m_RecordStorage.AddRecord(ppbRecord, pnIndex); + } + __checkReturn + inline HRESULT InsertRecord( + UINT32 nIndex, + BYTE **ppbRecord) + { + return m_RecordStorage.InsertRecord(nIndex, ppbRecord); + } + + // Makes table data writable, i.e. copies them into newly allocated chunk of memory. The caller + // guarantees that the table is not writable yet (otherwise this method asserts). + // + // Returns S_OK (even if the table is empty). + // Returns METADATA_E_INTERNAL_ERROR error code if the table has more segments. + __checkReturn + inline HRESULT MakeWritable() + { + return m_RecordStorage.ConvertToRW(); + } + +#ifdef _DEBUG_METADATA + // Sets table information for debugging. + void Debug_SetTableInfo(const char *szTableName, UINT32 nTableIndex) + { + } +#endif //_DEBUG_METADATA + +}; // class TableRW + +}; // namespace MetaData |