ALERROR CDataFile::DeleteEntry (int iEntry) // DeleteEntry // // Does some stuff { ALERROR error; DWORD dwOldBlock; DWORD dwOldBlockCount; ASSERT(IsOpen()); ASSERT(!m_fReadOnly); // Make sure we're in bounds if (iEntry < 0 || iEntry >= m_iEntryTableCount) return ERR_FAIL; if (m_pEntryTable[iEntry].dwBlock == FREE_ENTRY) return ERR_FAIL; // Delete it dwOldBlock = m_pEntryTable[iEntry].dwBlock; dwOldBlockCount = m_pEntryTable[iEntry].dwBlockCount; m_pEntryTable[iEntry].dwBlock = FREE_ENTRY; FreeBlockChain(dwOldBlock, dwOldBlockCount); // Flush if ((error = Flush())) return error; return NOERROR; }
void StormFixedBlockAllocator::FreeBlockChain(void * resolved_pointer, StormFixedBlockType::Index type) { FreeBlockChain(GetHandleForBlock(resolved_pointer), type); }
ALERROR CDataFile::ResizeEntry (int iEntry, DWORD dwSize, DWORD *retdwBlockCount) // ResizeEntry // // Changes the blocks associated with the given entry. Note that this // routine does not necessarily preserve the previous contents of // the entry { ALERROR error; DWORD dwBlockCount; // Figure out how many blocks we need to hold the entry dwBlockCount = (dwSize / (DWORD)m_iBlockSize) + 1; // If this is less than the number of blocks that we've // got allocated, free some if (dwBlockCount < m_pEntryTable[iEntry].dwBlockCount) { DWORD dwFreeBlocks = m_pEntryTable[iEntry].dwBlockCount - dwBlockCount; m_pEntryTable[iEntry].dwBlockCount = dwBlockCount; if ((error = FreeBlockChain(m_pEntryTable[iEntry].dwBlock + dwBlockCount, dwFreeBlocks))) return error; } // If this is more than the number of entries for this block // then we need to grow the block chain. else if (dwBlockCount > m_pEntryTable[iEntry].dwBlockCount) { DWORD dwOldBlock = m_pEntryTable[iEntry].dwBlock; DWORD dwOldBlockCount = m_pEntryTable[iEntry].dwBlockCount; DWORD dwStartingBlock; // Add a new entry if ((error = AllocBlockChain(dwBlockCount, &dwStartingBlock))) return error; // Store the new entry data m_pEntryTable[iEntry].dwBlock = dwStartingBlock; m_pEntryTable[iEntry].dwBlockCount = dwBlockCount; // Free the current block chain if ((error = FreeBlockChain(dwOldBlock, dwOldBlockCount))) return error; } // Set data length m_pEntryTable[iEntry].dwSize = dwSize; m_fEntryTableModified = TRUE; // Return the block count, if necessary if (retdwBlockCount) *retdwBlockCount = dwBlockCount; return NOERROR; }
ALERROR CDataFile::AddEntry (const CString &sData, int *retiEntry) // AddEntry // // Does some stuff { ALERROR error; int i, iEntry; DWORD dwStartingBlock; DWORD dwBlockCount; ASSERT(IsOpen()); ASSERT(!m_fReadOnly); // Look for a free entry for (i = 0; i < m_iEntryTableCount; i++) if (m_pEntryTable[i].dwBlock == FREE_ENTRY) break; // If we could not find a free entry, grow the entry table if (i == m_iEntryTableCount) { if ((error = GrowEntryTable(&iEntry))) goto Fail; } else iEntry = i; // Figure out how many blocks we need dwBlockCount = (sData.GetLength() / m_iBlockSize) + 1; // Allocate a block chain large enough to contain the entry if ((error = AllocBlockChain(dwBlockCount, &dwStartingBlock))) goto Fail; // Write the block chain if ((error = WriteBlockChain(dwStartingBlock, sData.GetPointer(), sData.GetLength()))) { FreeBlockChain(dwStartingBlock, dwBlockCount); goto Fail; } // Set the entry m_pEntryTable[iEntry].dwBlock = dwStartingBlock; m_pEntryTable[iEntry].dwBlockCount = dwBlockCount; m_pEntryTable[iEntry].dwSize = (DWORD)sData.GetLength(); m_pEntryTable[iEntry].dwFlags = 0; m_fEntryTableModified = TRUE; // Flush if ((error = Flush())) goto Fail; // Done *retiEntry = iEntry; return NOERROR; Fail: return error; }
ALERROR CDataFile::DeleteEntry (int iEntry) // DeleteEntry // // Does some stuff { ALERROR error; DWORD dwOldBlock; DWORD dwOldBlockCount; ASSERT(IsOpen()); ASSERT(!m_fReadOnly); // Make sure we're in bounds if (iEntry < 0 || iEntry >= m_iEntryTableCount) return ERR_FAIL; ENTRYSTRUCT *pEntry = &m_pEntryTable[iEntry]; if (pEntry->dwBlock == FREE_ENTRY) return ERR_FAIL; // Delete it the block that we own dwOldBlock = pEntry->dwBlock; dwOldBlockCount = pEntry->dwBlockCount; pEntry->dwBlock = FREE_ENTRY; FreeBlockChain(dwOldBlock, dwOldBlockCount); // The entry array may have changed inside FreeBlockChain, so we refresh pEntry = &m_pEntryTable[iEntry]; // If we're the latest entry, then we delete just this version if (pEntry->dwLatestEntry == (DWORD)INVALID_ENTRY) { if (pEntry->dwPrevEntry != (DWORD)INVALID_ENTRY) { ENTRYSTRUCT *pPrevEntry = &m_pEntryTable[pEntry->dwPrevEntry]; pEntry->dwBlock = pPrevEntry->dwBlock; pEntry->dwBlockCount = pPrevEntry->dwBlockCount; pEntry->dwSize = pPrevEntry->dwSize; pEntry->dwFlags = pPrevEntry->dwFlags; pEntry->dwVersion = pPrevEntry->dwVersion; pEntry->dwPrevEntry = pPrevEntry->dwPrevEntry; pEntry->dwLatestEntry = (DWORD)INVALID_ENTRY; pPrevEntry->dwBlock = FREE_ENTRY; } } // If this is not the latest entry, then we need to // fix up the chain else if (pEntry->dwLatestEntry != (DWORD)INVALID_ENTRY) { // Look for the version after this one int iNextEntry = (int)pEntry->dwLatestEntry; while (iNextEntry != INVALID_ENTRY && m_pEntryTable[iNextEntry].dwPrevEntry != (DWORD)iEntry) iNextEntry = (int)m_pEntryTable[iNextEntry].dwPrevEntry; // If we found it, then make the connection if (iNextEntry != INVALID_ENTRY) { ENTRYSTRUCT *pNextEntry = &m_pEntryTable[iNextEntry]; pNextEntry->dwPrevEntry = pEntry->dwPrevEntry; } } // Flush if (error = Flush()) return error; return NOERROR; }
void FMemArena::FreeAllBlocks() { FreeBlockChain(TopBlock); FreeBlockChain(FreeBlocks); }