packagefs: Use only one object_cache for all TwoKeyAVLTreeNodes.

Previously there were 6, all with the exact same object size.
This commit is contained in:
Augustin Cavalier
2024-08-31 13:15:17 -04:00
parent 706d9ddd10
commit b60fa5fa05
2 changed files with 39 additions and 44 deletions
@@ -19,6 +19,7 @@
#include <AutoDeleter.h>
#include <package/hpkg/PackageFileHeapAccessorBase.h>
#include "util/TwoKeyAVLTree.h"
#include "AttributeCookie.h"
#include "AttributeDirectoryCookie.h"
@@ -32,6 +33,8 @@
#include "Volume.h"
template<> object_cache* TwoKeyAVLTreeNode<void*>::sNodeCache = NULL;
static const uint32 kOptimalIOSize = 64 * 1024;
@@ -1085,6 +1088,9 @@ packagefs_std_ops(int32 op, ...)
PackageFileHeapAccessorBase::kChunkSize, sizeof(void*),
0, /* magazine capacity, count */ 2, 1, 0, NULL,
NULL, NULL, NULL);
TwoKeyAVLTreeNode<void*>::sNodeCache =
create_object_cache("pkgfs TKAVLTreeNodes",
sizeof(TwoKeyAVLTreeNode<void*>), 8, NULL, NULL, NULL);
error = PackageFSRoot::GlobalInit();
if (error != B_OK) {
@@ -1102,6 +1108,7 @@ packagefs_std_ops(int32 op, ...)
{
PRINT("package_std_ops(): B_MODULE_UNINIT\n");
PackageFSRoot::GlobalUninit();
delete_object_cache(TwoKeyAVLTreeNode<void*>::sNodeCache);
delete_object_cache((object_cache*)
PackageFileHeapAccessorBase::sChunkCache);
StringConstants::Cleanup();
@@ -138,12 +138,42 @@ public:
// #pragma mark - TwoKeyAVLTreeNodeStrategy
template<typename Value>
struct TwoKeyAVLTreeNode : AVLTreeNode {
static object_cache* sNodeCache;
static void* operator new(size_t size)
{
object_cache* cache = TwoKeyAVLTreeNode<void*>::sNodeCache;
const size_t nodeSize = sizeof(TwoKeyAVLTreeNode<void*>);
if (size != nodeSize || cache == NULL)
panic("unexpected size passed to operator new!");
return object_cache_alloc(cache, 0);
}
static void operator delete(void* object)
{
object_cache_free(TwoKeyAVLTreeNode<void*>::sNodeCache, object, 0);
}
public:
TwoKeyAVLTreeNode(const Value& value)
:
AVLTreeNode(),
value(value)
{
}
Value value;
};
template <typename PrimaryKey, typename SecondaryKey, typename Value,
typename PrimaryKeyCompare, typename SecondaryKeyCompare,
typename GetPrimaryKey, typename GetSecondaryKey>
class TwoKeyAVLTreeNodeStrategy {
public:
typedef TwoKeyAVLTreeKey<PrimaryKey, SecondaryKey> Key;
typedef TwoKeyAVLTreeNode<Value> Node;
TwoKeyAVLTreeNodeStrategy(
const PrimaryKeyCompare& primaryKeyCompare = PrimaryKeyCompare(),
@@ -156,58 +186,19 @@ public:
fGetPrimaryKey(getPrimaryKey),
fGetSecondaryKey(getSecondaryKey)
{
fObjectCache = create_object_cache("packagefs TwoKeyAVLTreeNodes", sizeof(Node), 8,
NULL, NULL, NULL);
fObjectCacheRefs = new int32(1);
}
TwoKeyAVLTreeNodeStrategy(const TwoKeyAVLTreeNodeStrategy& other)
:
fPrimaryKeyCompare(other.fPrimaryKeyCompare),
fSecondaryKeyCompare(other.fSecondaryKeyCompare),
fGetPrimaryKey(other.fGetPrimaryKey),
fGetSecondaryKey(other.fGetSecondaryKey),
fObjectCache(other.fObjectCache),
fObjectCacheRefs(other.fObjectCacheRefs)
{
atomic_add(fObjectCacheRefs, 1);
}
~TwoKeyAVLTreeNodeStrategy()
{
atomic_add(fObjectCacheRefs, -1);
if (atomic_get(fObjectCacheRefs) == 0) {
delete_object_cache(fObjectCache);
delete fObjectCacheRefs;
}
}
struct Node : AVLTreeNode {
static void* operator new(size_t size, object_cache* cache) {
if (size != sizeof(Node) || !cache)
panic("unexpected size passed to operator new!");
return object_cache_alloc(cache, 0);
}
Node(const Value& value)
:
AVLTreeNode(),
value(value)
{
}
Value value;
};
inline Node* Allocate(const Key& key, const Value& value) const
{
return new(fObjectCache) Node(value);
return new Node(value);
}
inline void Free(Node* node) const
{
if (node == NULL)
return;
object_cache_delete<Node>(fObjectCache, node, 0);
delete node;
}
// internal use (not part of the strategy)
@@ -260,9 +251,6 @@ private:
SecondaryKeyCompare fSecondaryKeyCompare;
GetPrimaryKey fGetPrimaryKey;
GetSecondaryKey fGetSecondaryKey;
object_cache* fObjectCache;
int32* fObjectCacheRefs;
};