kernel/fs: Refactor EntryCache to not use constant array sizes.
Instead set them in the Init functions. For now, the same hard-coded sizes are used, so aside from slightly increased storage on two classes (or not even due to padding), this has no functional change.
This commit is contained in:
parent
d02c0bade7
commit
25866ebeeb
@ -9,8 +9,6 @@
|
||||
#include <new>
|
||||
|
||||
|
||||
static const int32 kEntriesPerGeneration = 1024;
|
||||
|
||||
static const int32 kEntryNotInArray = -1;
|
||||
static const int32 kEntryRemoved = -2;
|
||||
|
||||
@ -33,14 +31,14 @@ EntryCacheGeneration::~EntryCacheGeneration()
|
||||
|
||||
|
||||
status_t
|
||||
EntryCacheGeneration::Init()
|
||||
EntryCacheGeneration::Init(int32 entriesSize)
|
||||
{
|
||||
entries = new(std::nothrow) EntryCacheEntry*[kEntriesPerGeneration];
|
||||
entries_size = entriesSize;
|
||||
entries = new(std::nothrow) EntryCacheEntry*[entries_size];
|
||||
if (entries == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
memset(entries, 0, sizeof(EntryCacheEntry*) * kEntriesPerGeneration);
|
||||
|
||||
memset(entries, 0, sizeof(EntryCacheEntry*) * entries_size);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@ -67,6 +65,7 @@ EntryCache::~EntryCache()
|
||||
free(entry);
|
||||
entry = next;
|
||||
}
|
||||
delete[] fGenerations;
|
||||
|
||||
rw_lock_destroy(&fLock);
|
||||
}
|
||||
@ -79,8 +78,12 @@ EntryCache::Init()
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
for (int32 i = 0; i < kGenerationCount; i++) {
|
||||
error = fGenerations[i].Init();
|
||||
fGenerationCount = 8;
|
||||
int32 entriesSize = 1024;
|
||||
|
||||
fGenerations = new(std::nothrow) EntryCacheGeneration[fGenerationCount];
|
||||
for (int32 i = 0; i < fGenerationCount; i++) {
|
||||
error = fGenerations[i].Init(entriesSize);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
}
|
||||
@ -96,6 +99,9 @@ EntryCache::Add(ino_t dirID, const char* name, ino_t nodeID, bool missing)
|
||||
|
||||
WriteLocker _(fLock);
|
||||
|
||||
if (fGenerationCount == 0)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
EntryCacheEntry* entry = fEntries.Lookup(key);
|
||||
if (entry != NULL) {
|
||||
entry->node_id = nodeID;
|
||||
@ -168,8 +174,8 @@ EntryCache::Lookup(ino_t dirID, const char* name, ino_t& _nodeID,
|
||||
if (entry == NULL)
|
||||
return false;
|
||||
|
||||
int32 oldGeneration = atomic_get_and_set(&entry->generation,
|
||||
fCurrentGeneration);
|
||||
const int32 oldGeneration = atomic_get_and_set(&entry->generation,
|
||||
fCurrentGeneration);
|
||||
if (oldGeneration == fCurrentGeneration || entry->index < 0) {
|
||||
// The entry is already in the current generation or is being moved to
|
||||
// it by another thread.
|
||||
@ -183,8 +189,8 @@ EntryCache::Lookup(ino_t dirID, const char* name, ino_t& _nodeID,
|
||||
entry->index = kEntryNotInArray;
|
||||
|
||||
// add to the current generation
|
||||
int32 index = atomic_add(&fGenerations[oldGeneration].next_index, 1);
|
||||
if (index < kEntriesPerGeneration) {
|
||||
const int32 index = atomic_add(&fGenerations[oldGeneration].next_index, 1);
|
||||
if (index < fGenerations[fCurrentGeneration].entries_size) {
|
||||
fGenerations[fCurrentGeneration].entries[index] = entry;
|
||||
entry->index = index;
|
||||
_nodeID = entry->node_id;
|
||||
@ -230,9 +236,11 @@ EntryCache::DebugReverseLookup(ino_t nodeID, ino_t& _dirID)
|
||||
void
|
||||
EntryCache::_AddEntryToCurrentGeneration(EntryCacheEntry* entry)
|
||||
{
|
||||
ASSERT_WRITE_LOCKED_RW_LOCK(&fLock);
|
||||
|
||||
// the generation might not be full yet
|
||||
int32 index = fGenerations[fCurrentGeneration].next_index++;
|
||||
if (index < kEntriesPerGeneration) {
|
||||
if (index < fGenerations[fCurrentGeneration].entries_size) {
|
||||
fGenerations[fCurrentGeneration].entries[index] = entry;
|
||||
entry->generation = fCurrentGeneration;
|
||||
entry->index = index;
|
||||
@ -240,8 +248,8 @@ EntryCache::_AddEntryToCurrentGeneration(EntryCacheEntry* entry)
|
||||
}
|
||||
|
||||
// we have to clear the oldest generation
|
||||
int32 newGeneration = (fCurrentGeneration + 1) % kGenerationCount;
|
||||
for (int32 i = 0; i < kEntriesPerGeneration; i++) {
|
||||
const int32 newGeneration = (fCurrentGeneration + 1) % fGenerationCount;
|
||||
for (int32 i = 0; i < fGenerations[newGeneration].entries_size; i++) {
|
||||
EntryCacheEntry* otherEntry = fGenerations[newGeneration].entries[i];
|
||||
if (otherEntry == NULL)
|
||||
continue;
|
||||
@ -253,8 +261,8 @@ EntryCache::_AddEntryToCurrentGeneration(EntryCacheEntry* entry)
|
||||
|
||||
// set the new generation and add the entry
|
||||
fCurrentGeneration = newGeneration;
|
||||
fGenerations[newGeneration].next_index = 1;
|
||||
fGenerations[newGeneration].entries[0] = entry;
|
||||
fGenerations[newGeneration].next_index = 1;
|
||||
entry->generation = newGeneration;
|
||||
entry->index = 0;
|
||||
}
|
||||
|
@ -44,12 +44,13 @@ struct EntryCacheEntry {
|
||||
|
||||
struct EntryCacheGeneration {
|
||||
int32 next_index;
|
||||
int32 entries_size;
|
||||
EntryCacheEntry** entries;
|
||||
|
||||
EntryCacheGeneration();
|
||||
~EntryCacheGeneration();
|
||||
|
||||
status_t Init();
|
||||
status_t Init(int32 entriesSize);
|
||||
};
|
||||
|
||||
|
||||
@ -99,8 +100,6 @@ public:
|
||||
const char* DebugReverseLookup(ino_t nodeID, ino_t& _dirID);
|
||||
|
||||
private:
|
||||
static const int32 kGenerationCount = 8;
|
||||
|
||||
typedef BOpenHashTable<EntryCacheHashDefinition> EntryTable;
|
||||
typedef DoublyLinkedList<EntryCacheEntry> EntryList;
|
||||
|
||||
@ -111,7 +110,8 @@ private:
|
||||
private:
|
||||
rw_lock fLock;
|
||||
EntryTable fEntries;
|
||||
EntryCacheGeneration fGenerations[kGenerationCount];
|
||||
int32 fGenerationCount;
|
||||
EntryCacheGeneration* fGenerations;
|
||||
int32 fCurrentGeneration;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user