Add Index base class and index table in Volume
This commit is contained in:
@@ -0,0 +1,205 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2011, Ingo Weinhold, [email protected].
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "Index.h"
|
||||||
|
|
||||||
|
#include "DebugSupport.h"
|
||||||
|
#include "Node.h"
|
||||||
|
#include "IndexImpl.h"
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - Index
|
||||||
|
|
||||||
|
|
||||||
|
Index::Index()
|
||||||
|
:
|
||||||
|
fVolume(NULL),
|
||||||
|
fName(NULL),
|
||||||
|
fType(0),
|
||||||
|
fKeyLength(0),
|
||||||
|
fFixedKeyLength(true)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Index::~Index()
|
||||||
|
{
|
||||||
|
free(fName);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
Index::Init(Volume* volume, const char* name, uint32 type, bool fixedKeyLength,
|
||||||
|
size_t keyLength)
|
||||||
|
{
|
||||||
|
fName = strdup(name);
|
||||||
|
if (fName == NULL)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
|
fVolume = volume;
|
||||||
|
fType = type;
|
||||||
|
fKeyLength = keyLength;
|
||||||
|
fFixedKeyLength = fixedKeyLength;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
Index::GetIterator(IndexIterator* iterator)
|
||||||
|
{
|
||||||
|
bool result = false;
|
||||||
|
if (iterator) {
|
||||||
|
AbstractIndexIterator* actualIterator = InternalGetIterator();
|
||||||
|
if (actualIterator) {
|
||||||
|
iterator->SetIterator(actualIterator);
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
Index::Find(const void* key, size_t length, IndexIterator* iterator)
|
||||||
|
{
|
||||||
|
bool result = false;
|
||||||
|
if (key && iterator) {
|
||||||
|
AbstractIndexIterator* actualIterator = InternalFind(key, length);
|
||||||
|
if (actualIterator) {
|
||||||
|
iterator->SetIterator(actualIterator);
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Index::Dump()
|
||||||
|
{
|
||||||
|
D(
|
||||||
|
PRINT(("Index: `%s', type: %lx\n", Name(), Type()));
|
||||||
|
for (IndexIterator it(this); it.Current(); it.Next()) {
|
||||||
|
Node* node = it.Current();
|
||||||
|
PRINT((" node: `%s', dir: %lld\n", node->GetName(),
|
||||||
|
node->Parent()->ID()));
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - IndexIterator
|
||||||
|
|
||||||
|
|
||||||
|
IndexIterator::IndexIterator()
|
||||||
|
:
|
||||||
|
fIterator(NULL)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
IndexIterator::IndexIterator(Index* index)
|
||||||
|
:
|
||||||
|
fIterator(NULL)
|
||||||
|
{
|
||||||
|
if (index)
|
||||||
|
index->GetIterator(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
IndexIterator::~IndexIterator()
|
||||||
|
{
|
||||||
|
SetIterator(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Node*
|
||||||
|
IndexIterator::Current()
|
||||||
|
{
|
||||||
|
return fIterator != NULL ? fIterator->Current() : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Node*
|
||||||
|
IndexIterator::Current(void* buffer, size_t* _keyLength)
|
||||||
|
{
|
||||||
|
return fIterator != NULL ? fIterator->Current(buffer, _keyLength) : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Node*
|
||||||
|
IndexIterator::Previous()
|
||||||
|
{
|
||||||
|
return fIterator != NULL ? fIterator->Previous() : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Node*
|
||||||
|
IndexIterator::Next()
|
||||||
|
{
|
||||||
|
return fIterator != NULL ? fIterator->Next() : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Node*
|
||||||
|
IndexIterator::Next(void* buffer, size_t* _keyLength)
|
||||||
|
{
|
||||||
|
Node* node = NULL;
|
||||||
|
if (fIterator != NULL && fIterator->Next())
|
||||||
|
node = Current(buffer, _keyLength);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
IndexIterator::Suspend()
|
||||||
|
{
|
||||||
|
return fIterator != NULL ? fIterator->Suspend() : B_BAD_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
IndexIterator::Resume()
|
||||||
|
{
|
||||||
|
return fIterator != NULL ? fIterator->Resume() : B_BAD_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
IndexIterator::SetIterator(AbstractIndexIterator* iterator)
|
||||||
|
{
|
||||||
|
delete fIterator;
|
||||||
|
fIterator = iterator;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - AbstractIndexIterator
|
||||||
|
|
||||||
|
|
||||||
|
AbstractIndexIterator::AbstractIndexIterator()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
AbstractIndexIterator::~AbstractIndexIterator()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
AbstractIndexIterator::Suspend()
|
||||||
|
{
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
AbstractIndexIterator::Resume()
|
||||||
|
{
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,128 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2011, Ingo Weinhold, [email protected].
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
#ifndef INDEX_H
|
||||||
|
#define INDEX_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <SupportDefs.h>
|
||||||
|
|
||||||
|
#include <util/khash.h>
|
||||||
|
#include <util/OpenHashTable.h>
|
||||||
|
|
||||||
|
|
||||||
|
class AbstractIndexIterator;
|
||||||
|
class IndexIterator;
|
||||||
|
class Node;
|
||||||
|
class Volume;
|
||||||
|
|
||||||
|
|
||||||
|
static const size_t kMaxIndexKeyLength = 256;
|
||||||
|
|
||||||
|
|
||||||
|
class Index {
|
||||||
|
public:
|
||||||
|
Index();
|
||||||
|
virtual ~Index();
|
||||||
|
|
||||||
|
status_t Init(Volume* volume, const char* name,
|
||||||
|
uint32 type, bool fixedKeyLength,
|
||||||
|
size_t keyLength = 0);
|
||||||
|
|
||||||
|
Volume* GetVolume() const { return fVolume; }
|
||||||
|
|
||||||
|
const char* Name() const { return fName; }
|
||||||
|
uint32 Type() const { return fType; }
|
||||||
|
bool HasFixedKeyLength() const
|
||||||
|
{ return fFixedKeyLength; }
|
||||||
|
size_t KeyLength() const { return fKeyLength; }
|
||||||
|
|
||||||
|
virtual int32 CountEntries() const = 0;
|
||||||
|
|
||||||
|
bool GetIterator(IndexIterator* iterator);
|
||||||
|
bool Find(const void* key, size_t length,
|
||||||
|
IndexIterator* iterator);
|
||||||
|
|
||||||
|
Index*& IndexHashLink()
|
||||||
|
{ return fHashLink; }
|
||||||
|
|
||||||
|
// debugging
|
||||||
|
void Dump();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual AbstractIndexIterator* InternalGetIterator() = 0;
|
||||||
|
virtual AbstractIndexIterator* InternalFind(const void* key,
|
||||||
|
size_t length) = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Index* fHashLink;
|
||||||
|
Volume* fVolume;
|
||||||
|
char* fName;
|
||||||
|
uint32 fType;
|
||||||
|
size_t fKeyLength;
|
||||||
|
bool fFixedKeyLength;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class IndexIterator {
|
||||||
|
public:
|
||||||
|
IndexIterator();
|
||||||
|
IndexIterator(Index* index);
|
||||||
|
~IndexIterator();
|
||||||
|
|
||||||
|
Node* Current();
|
||||||
|
Node* Current(void* buffer, size_t* _keyLength);
|
||||||
|
Node* Previous();
|
||||||
|
Node* Next();
|
||||||
|
Node* Next(void* buffer, size_t* _keyLength);
|
||||||
|
|
||||||
|
status_t Suspend();
|
||||||
|
status_t Resume();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void SetIterator(AbstractIndexIterator* iterator);
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class Index;
|
||||||
|
|
||||||
|
private:
|
||||||
|
AbstractIndexIterator* fIterator;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - IndexHashDefinition
|
||||||
|
|
||||||
|
|
||||||
|
struct IndexHashDefinition {
|
||||||
|
typedef const char* KeyType;
|
||||||
|
typedef Index ValueType;
|
||||||
|
|
||||||
|
size_t HashKey(const char* key) const
|
||||||
|
{
|
||||||
|
return key != NULL ? hash_hash_string(key) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Hash(const Index* value) const
|
||||||
|
{
|
||||||
|
return HashKey(value->Name());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Compare(const char* key, const Index* value) const
|
||||||
|
{
|
||||||
|
return strcmp(value->Name(), key) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Index*& GetLink(Index* value) const
|
||||||
|
{
|
||||||
|
return value->IndexHashLink();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
typedef BOpenHashTable<IndexHashDefinition> IndexHashTable;
|
||||||
|
|
||||||
|
|
||||||
|
#endif // INDEX_H
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2011, Ingo Weinhold, [email protected].
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
#ifndef INDEX_IMPL_H
|
||||||
|
#define INDEX_IMPL_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "Index.h"
|
||||||
|
#include "Node.h"
|
||||||
|
|
||||||
|
|
||||||
|
class AbstractIndexIterator {
|
||||||
|
public:
|
||||||
|
AbstractIndexIterator();
|
||||||
|
virtual ~AbstractIndexIterator();
|
||||||
|
|
||||||
|
virtual Node* Current() = 0;
|
||||||
|
virtual Node* Current(void* buffer, size_t* _keyLength) = 0;
|
||||||
|
virtual Node* Previous() = 0;
|
||||||
|
virtual Node* Next() = 0;
|
||||||
|
|
||||||
|
virtual status_t Suspend();
|
||||||
|
virtual status_t Resume();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // INDEX_IMPL_H
|
||||||
@@ -16,6 +16,7 @@ HAIKU_PACKAGE_FS_SOURCES =
|
|||||||
Directory.cpp
|
Directory.cpp
|
||||||
EmptyAttributeDirectoryCookie.cpp
|
EmptyAttributeDirectoryCookie.cpp
|
||||||
GlobalFactory.cpp
|
GlobalFactory.cpp
|
||||||
|
Index.cpp
|
||||||
kernel_interface.cpp
|
kernel_interface.cpp
|
||||||
Node.cpp
|
Node.cpp
|
||||||
NodeListener.cpp
|
NodeListener.cpp
|
||||||
|
|||||||
@@ -460,6 +460,14 @@ Volume::~Volume()
|
|||||||
while (PackageDomain* packageDomain = fPackageDomains.Head())
|
while (PackageDomain* packageDomain = fPackageDomains.Head())
|
||||||
_RemovePackageDomain(packageDomain);
|
_RemovePackageDomain(packageDomain);
|
||||||
|
|
||||||
|
// delete all indices
|
||||||
|
Index* index = fIndices.Clear(true);
|
||||||
|
while (index != NULL) {
|
||||||
|
Index* next = index->IndexHashLink();
|
||||||
|
delete index;
|
||||||
|
index = next;
|
||||||
|
}
|
||||||
|
|
||||||
// remove all nodes from the ID hash table
|
// remove all nodes from the ID hash table
|
||||||
Node* node = fNodes.Clear(true);
|
Node* node = fNodes.Clear(true);
|
||||||
while (node != NULL) {
|
while (node != NULL) {
|
||||||
@@ -495,6 +503,10 @@ Volume::Mount(const char* parameterString)
|
|||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
RETURN_ERROR(error);
|
RETURN_ERROR(error);
|
||||||
|
|
||||||
|
error = fIndices.Init();
|
||||||
|
if (error != B_OK)
|
||||||
|
RETURN_ERROR(error);
|
||||||
|
|
||||||
// get the mount parameters
|
// get the mount parameters
|
||||||
const char* packages = NULL;
|
const char* packages = NULL;
|
||||||
const char* volumeName = NULL;
|
const char* volumeName = NULL;
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
#include <util/DoublyLinkedList.h>
|
#include <util/DoublyLinkedList.h>
|
||||||
#include <util/KMessage.h>
|
#include <util/KMessage.h>
|
||||||
|
|
||||||
|
#include "Index.h"
|
||||||
#include "Node.h"
|
#include "Node.h"
|
||||||
#include "NodeListener.h"
|
#include "NodeListener.h"
|
||||||
#include "PackageDomain.h"
|
#include "PackageDomain.h"
|
||||||
@@ -71,6 +72,9 @@ public:
|
|||||||
Node* node);
|
Node* node);
|
||||||
void RemoveNodeListener(NodeListener* listener);
|
void RemoveNodeListener(NodeListener* listener);
|
||||||
|
|
||||||
|
Index* FindIndex(const char* name) const
|
||||||
|
{ return fIndices.Lookup(name); }
|
||||||
|
|
||||||
// VFS wrappers
|
// VFS wrappers
|
||||||
status_t GetVNode(ino_t nodeID, Node*& _node);
|
status_t GetVNode(ino_t nodeID, Node*& _node);
|
||||||
status_t PutVNode(ino_t nodeID);
|
status_t PutVNode(ino_t nodeID);
|
||||||
@@ -188,6 +192,7 @@ private:
|
|||||||
|
|
||||||
NodeIDHashTable fNodes;
|
NodeIDHashTable fNodes;
|
||||||
NodeListenerHashTable fNodeListeners;
|
NodeListenerHashTable fNodeListeners;
|
||||||
|
IndexHashTable fIndices;
|
||||||
|
|
||||||
JobList fJobQueue;
|
JobList fJobQueue;
|
||||||
mutex fJobQueueLock;
|
mutex fJobQueueLock;
|
||||||
|
|||||||
Reference in New Issue
Block a user