* Copyright 2001-2010, Haiku Inc. All rights reserved.
* This file may be used under the terms of the MIT License.
*
* Authors:
* Janito V. Ferreira Filho
*/
#include "HashRevokeManager.h"
#include <new>
#ifdef TRACE_EXT2
# define TRACE(x...) dprintf("\33[34mext2:\33[0m " x)
#else
# define TRACE(x...) ;
#endif
HashRevokeManager::HashRevokeManager(bool has64bits)
: RevokeManager(has64bits),
fHash(NULL),
kInitialHashSize(128)
{
}
HashRevokeManager::~HashRevokeManager()
{
if (fHash != NULL) {
if (fRevokeCount != 0) {
RevokeElement *element = fHash->Clear(true);
while (element != NULL) {
RevokeElement* next = element->next;
delete element;
element = next;
}
}
delete fHash;
}
}
status_t
HashRevokeManager::Init()
{
fHash = new(std::nothrow) RevokeTable();
if (fHash == NULL || fHash->Init(kInitialHashSize) != B_OK)
return B_NO_MEMORY;
return B_OK;
}
status_t
HashRevokeManager::Insert(uint32 block, uint32 commitID)
{
RevokeElement* element = fHash->Lookup(block);
if (element != NULL) {
TRACE("HashRevokeManager::Insert(): Already has an element\n");
if (element->commitID < commitID) {
TRACE("HashRevokeManager::Insert(): Deleting previous element\n");
bool retValue = fHash->Remove(element);
if (!retValue)
return B_ERROR;
delete element;
} else {
return B_OK;
}
}
return _ForceInsert(block, commitID);
}
status_t
HashRevokeManager::Remove(uint32 block)
{
RevokeElement* element = fHash->Lookup(block);
if (element == NULL)
return B_ERROR;
fHash->Remove(element);
delete element;
return B_OK;
}
bool
HashRevokeManager::Lookup(uint32 block, uint32 commitID)
{
RevokeElement* element = fHash->Lookup(block);
if (element == NULL)
return false;
return element->commitID >= commitID;
}
int
HashRevokeManager::Compare(void* _revoked, const void *_block)
{
RevokeElement* revoked = (RevokeElement*)_revoked;
uint32 block = *(uint32*)_block;
if (revoked->block == block)
return 0;
return (revoked->block > block) ? 1 : -1;
}
uint32
HashRevokeManager::Hash(void* _revoked, const void* _block, uint32 range)
{
TRACE("HashRevokeManager::Hash(): revoked: %p, block: %p, range: %"
B_PRIu32 "\n", _revoked, _block, range);
RevokeElement* revoked = (RevokeElement*)_revoked;
if (revoked != NULL)
return revoked->block % range;
uint32 block = *(uint32*)_block;
return block % range;
}
status_t
HashRevokeManager::_ForceInsert(uint32 block, uint32 commitID)
{
RevokeElement* element = new(std::nothrow) RevokeElement;
if (element == NULL)
return B_NO_MEMORY;
element->block = block;
element->commitID = commitID;
status_t retValue = fHash->Insert(element);
if (retValue == B_OK) {
fRevokeCount++;
TRACE("HashRevokeManager::_ForceInsert(): revoke count: %" B_PRIu32
"\n", fRevokeCount);
}
return retValue;
}