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 <AutoDeleter.h>
#include <package/hpkg/PackageFileHeapAccessorBase.h> #include <package/hpkg/PackageFileHeapAccessorBase.h>
#include "util/TwoKeyAVLTree.h"
#include "AttributeCookie.h" #include "AttributeCookie.h"
#include "AttributeDirectoryCookie.h" #include "AttributeDirectoryCookie.h"
@@ -32,6 +33,8 @@
#include "Volume.h" #include "Volume.h"
template<> object_cache* TwoKeyAVLTreeNode<void*>::sNodeCache = NULL;
static const uint32 kOptimalIOSize = 64 * 1024; static const uint32 kOptimalIOSize = 64 * 1024;
@@ -1085,6 +1088,9 @@ packagefs_std_ops(int32 op, ...)
PackageFileHeapAccessorBase::kChunkSize, sizeof(void*), PackageFileHeapAccessorBase::kChunkSize, sizeof(void*),
0, /* magazine capacity, count */ 2, 1, 0, NULL, 0, /* magazine capacity, count */ 2, 1, 0, NULL,
NULL, NULL, NULL); NULL, NULL, NULL);
TwoKeyAVLTreeNode<void*>::sNodeCache =
create_object_cache("pkgfs TKAVLTreeNodes",
sizeof(TwoKeyAVLTreeNode<void*>), 8, NULL, NULL, NULL);
error = PackageFSRoot::GlobalInit(); error = PackageFSRoot::GlobalInit();
if (error != B_OK) { if (error != B_OK) {
@@ -1102,6 +1108,7 @@ packagefs_std_ops(int32 op, ...)
{ {
PRINT("package_std_ops(): B_MODULE_UNINIT\n"); PRINT("package_std_ops(): B_MODULE_UNINIT\n");
PackageFSRoot::GlobalUninit(); PackageFSRoot::GlobalUninit();
delete_object_cache(TwoKeyAVLTreeNode<void*>::sNodeCache);
delete_object_cache((object_cache*) delete_object_cache((object_cache*)
PackageFileHeapAccessorBase::sChunkCache); PackageFileHeapAccessorBase::sChunkCache);
StringConstants::Cleanup(); StringConstants::Cleanup();
@@ -138,12 +138,42 @@ public:
// #pragma mark - TwoKeyAVLTreeNodeStrategy // #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, template <typename PrimaryKey, typename SecondaryKey, typename Value,
typename PrimaryKeyCompare, typename SecondaryKeyCompare, typename PrimaryKeyCompare, typename SecondaryKeyCompare,
typename GetPrimaryKey, typename GetSecondaryKey> typename GetPrimaryKey, typename GetSecondaryKey>
class TwoKeyAVLTreeNodeStrategy { class TwoKeyAVLTreeNodeStrategy {
public: public:
typedef TwoKeyAVLTreeKey<PrimaryKey, SecondaryKey> Key; typedef TwoKeyAVLTreeKey<PrimaryKey, SecondaryKey> Key;
typedef TwoKeyAVLTreeNode<Value> Node;
TwoKeyAVLTreeNodeStrategy( TwoKeyAVLTreeNodeStrategy(
const PrimaryKeyCompare& primaryKeyCompare = PrimaryKeyCompare(), const PrimaryKeyCompare& primaryKeyCompare = PrimaryKeyCompare(),
@@ -156,58 +186,19 @@ public:
fGetPrimaryKey(getPrimaryKey), fGetPrimaryKey(getPrimaryKey),
fGetSecondaryKey(getSecondaryKey) 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() ~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 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 inline void Free(Node* node) const
{ {
if (node == NULL) delete node;
return;
object_cache_delete<Node>(fObjectCache, node, 0);
} }
// internal use (not part of the strategy) // internal use (not part of the strategy)
@@ -260,9 +251,6 @@ private:
SecondaryKeyCompare fSecondaryKeyCompare; SecondaryKeyCompare fSecondaryKeyCompare;
GetPrimaryKey fGetPrimaryKey; GetPrimaryKey fGetPrimaryKey;
GetSecondaryKey fGetSecondaryKey; GetSecondaryKey fGetSecondaryKey;
object_cache* fObjectCache;
int32* fObjectCacheRefs;
}; };