diff --git a/ext/filesystem.cpp b/ext/filesystem.cpp index d18cf541..a83964d9 100644 --- a/ext/filesystem.cpp +++ b/ext/filesystem.cpp @@ -51,6 +51,8 @@ Filesystem::Filesystem(Device* device) mru_inode = NULL; lru_inode = NULL; dirty_inode = NULL; + for ( size_t i = 0; i < INODE_HASH_LENGTH; i++ ) + hash_inodes[i] = NULL; inode_size = this->sb->s_inode_size; num_blocks = sb->s_blocks_count; num_groups = divup(this->sb->s_blocks_count, this->sb->s_blocks_per_group); @@ -140,7 +142,8 @@ Inode* Filesystem::GetInode(uint32_t inode_id) assert(inode_id); assert(inode_id < num_inodes); - for ( Inode* iter = mru_inode; iter; iter = iter->next_inode ) + size_t bin = inode_id % INODE_HASH_LENGTH; + for ( Inode* iter = hash_inodes[bin]; iter; iter = iter->next_hashed ) if ( iter->inode_id == inode_id ) return iter->Refer(), iter; diff --git a/ext/filesystem.h b/ext/filesystem.h index dba12006..2c1ebdfc 100644 --- a/ext/filesystem.h +++ b/ext/filesystem.h @@ -27,6 +27,8 @@ class BlockGroup; class Device; class Inode; +const size_t INODE_HASH_LENGTH = 1 << 16; + class Filesystem { public: @@ -46,6 +48,7 @@ public: Inode* mru_inode; Inode* lru_inode; Inode* dirty_inode; + Inode* hash_inodes[INODE_HASH_LENGTH]; time_t mtime_realtime; time_t mtime_monotonic; bool dirty; diff --git a/ext/inode.cpp b/ext/inode.cpp index 85eb8113..afce1c47 100644 --- a/ext/inode.cpp +++ b/ext/inode.cpp @@ -53,6 +53,8 @@ Inode::Inode(Filesystem* filesystem, uint32_t inode_id) { this->prev_inode = NULL; this->next_inode = NULL; + this->prev_hashed = NULL; + this->next_hashed = NULL; this->prev_dirty = NULL; this->next_dirty = NULL; this->filesystem = filesystem; @@ -1008,6 +1010,9 @@ void Inode::Unlink() { (prev_inode ? prev_inode->next_inode : filesystem->mru_inode) = next_inode; (next_inode ? next_inode->prev_inode : filesystem->lru_inode) = prev_inode; + size_t bin = inode_id % INODE_HASH_LENGTH; + (prev_hashed ? prev_hashed->next_hashed : filesystem->hash_inodes[bin]) = next_hashed; + if ( next_hashed ) next_hashed->prev_hashed = prev_hashed; } void Inode::Prelink() @@ -1019,4 +1024,10 @@ void Inode::Prelink() filesystem->mru_inode = this; if ( !filesystem->lru_inode ) filesystem->lru_inode = this; + size_t bin = inode_id % INODE_HASH_LENGTH; + prev_hashed = NULL; + next_hashed = filesystem->hash_inodes[bin]; + filesystem->hash_inodes[bin] = this; + if ( next_hashed ) + next_hashed->prev_hashed = this; } diff --git a/ext/inode.h b/ext/inode.h index e2a5613d..e11c2010 100644 --- a/ext/inode.h +++ b/ext/inode.h @@ -35,6 +35,8 @@ public: public: Inode* prev_inode; Inode* next_inode; + Inode* prev_hashed; + Inode* next_hashed; Inode* prev_dirty; Inode* next_dirty; Block* data_block;