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:
@@ -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;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user