/* We map in PAGE_SIZE-sized chunks. Must be a multiple of 4096. */
#define PAGE_SIZE 131072
-#define BLOCKS_PER_PAGE (PAGE_SIZE / BIG_BLOCK_SIZE)
-
/* We keep a list of recently-discarded pages. This controls the
* size of that list. */
#define MAX_VICTIM_PAGES 16
-/* This structure provides one bit for each block in a page.
- * Use BIGBLOCKFILE_{Test,Set,Clear}Bit to manipulate it. */
-typedef struct
-{
- unsigned int bits[BLOCKS_PER_PAGE / (CHAR_BIT * sizeof(unsigned int))];
-} BlockBits;
-
/***
* This structure identifies the paged that are mapped
* from the file and their position in memory. It is
DWORD mapped_bytes;
LPVOID lpBytes;
LONG refcnt;
-
- BlockBits readable_blocks;
- BlockBits writable_blocks;
};
struct BigBlockFile
{
BOOL fileBased;
ULARGE_INTEGER filesize;
- ULONG blocksize;
HANDLE hfile;
HANDLE hfilemap;
DWORD flProtect;
* pass expressions with side effects. */
#define ROUND_UP(a, b) ((((a) + (b) - 1)/(b))*(b))
-/***********************************************************
- * Blockbits functions.
- */
-static inline BOOL BIGBLOCKFILE_TestBit(const BlockBits *bb,
- unsigned int index)
-{
- unsigned int array_index = index / (CHAR_BIT * sizeof(unsigned int));
- unsigned int bit_index = index % (CHAR_BIT * sizeof(unsigned int));
-
- return bb->bits[array_index] & (1 << bit_index);
-}
-
-static inline void BIGBLOCKFILE_SetBit(BlockBits *bb, unsigned int index)
-{
- unsigned int array_index = index / (CHAR_BIT * sizeof(unsigned int));
- unsigned int bit_index = index % (CHAR_BIT * sizeof(unsigned int));
-
- bb->bits[array_index] |= (1 << bit_index);
-}
-
-static inline void BIGBLOCKFILE_ClearBit(BlockBits *bb, unsigned int index)
-{
- unsigned int array_index = index / (CHAR_BIT * sizeof(unsigned int));
- unsigned int bit_index = index % (CHAR_BIT * sizeof(unsigned int));
-
- bb->bits[array_index] &= ~(1 << bit_index);
-}
-
-static inline void BIGBLOCKFILE_Zero(BlockBits *bb)
-{
- memset(bb->bits, 0, sizeof(bb->bits));
-}
-
/******************************************************************************
* BIGBLOCKFILE_FileInit
*
return NULL;
}
- BIGBLOCKFILE_Zero(&page->readable_blocks);
- BIGBLOCKFILE_Zero(&page->writable_blocks);
-
return page;
}
if (page)
{
This->num_victim_pages--;
-
- BIGBLOCKFILE_Zero(&page->readable_blocks);
- BIGBLOCKFILE_Zero(&page->writable_blocks);
}
}
* and the blocks in use list.
*/
BigBlockFile *BIGBLOCKFILE_Construct(HANDLE hFile, ILockBytes* pLkByt, DWORD openFlags,
- ULONG blocksize, BOOL fileBased)
+ BOOL fileBased)
{
BigBlockFile *This;
This->fileBased = fileBased;
This->flProtect = BIGBLOCKFILE_GetProtectMode(openFlags);
- This->blocksize = blocksize;
This->maplist = NULL;
This->victimhead = NULL;
}
/******************************************************************************
- * BIGBLOCKFILE_EnsureExists
+ * BIGBLOCKFILE_Expand
*
- * Grows the file if necessary to make sure the block is valid.
+ * Grows the file to the specified size if necessary.
*/
-HRESULT BIGBLOCKFILE_EnsureExists(BigBlockFile *This, ULONG index)
+HRESULT BIGBLOCKFILE_Expand(BigBlockFile *This, ULARGE_INTEGER newSize)
{
ULARGE_INTEGER size;
HRESULT hr;
- /* Block index starts at -1 translate to zero based index */
- if (index == 0xffffffff)
- index = 0;
- else
- index++;
-
hr = BIGBLOCKFILE_GetSize(This, &size);
if(FAILED(hr)) return hr;
- /* make sure that the block physically exists */
- if ((This->blocksize * (index + 1)) > size.QuadPart)
- {
- ULARGE_INTEGER newSize;
-
- newSize.QuadPart = This->blocksize * (index + 1);
+ if (newSize.QuadPart > size.QuadPart)
hr = BIGBLOCKFILE_SetSize(This, newSize);
- }
return hr;
}