Add Index base class and index table in Volume
This commit is contained in:
parent
67f11c47a7
commit
804a92da7a
205
src/add-ons/kernel/file_systems/packagefs/Index.cpp
Normal file
205
src/add-ons/kernel/file_systems/packagefs/Index.cpp
Normal file
@ -0,0 +1,205 @@
|
||||
/*
|
||||
* Copyright 2011, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* 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;
|
||||
}
|
||||
|
128
src/add-ons/kernel/file_systems/packagefs/Index.h
Normal file
128
src/add-ons/kernel/file_systems/packagefs/Index.h
Normal file
@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Copyright 2011, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* 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
|
28
src/add-ons/kernel/file_systems/packagefs/IndexImpl.h
Normal file
28
src/add-ons/kernel/file_systems/packagefs/IndexImpl.h
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2011, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* 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
|
||||
EmptyAttributeDirectoryCookie.cpp
|
||||
GlobalFactory.cpp
|
||||
Index.cpp
|
||||
kernel_interface.cpp
|
||||
Node.cpp
|
||||
NodeListener.cpp
|
||||
|
@ -460,6 +460,14 @@ Volume::~Volume()
|
||||
while (PackageDomain* packageDomain = fPackageDomains.Head())
|
||||
_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
|
||||
Node* node = fNodes.Clear(true);
|
||||
while (node != NULL) {
|
||||
@ -495,6 +503,10 @@ Volume::Mount(const char* parameterString)
|
||||
if (error != B_OK)
|
||||
RETURN_ERROR(error);
|
||||
|
||||
error = fIndices.Init();
|
||||
if (error != B_OK)
|
||||
RETURN_ERROR(error);
|
||||
|
||||
// get the mount parameters
|
||||
const char* packages = NULL;
|
||||
const char* volumeName = NULL;
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include <util/DoublyLinkedList.h>
|
||||
#include <util/KMessage.h>
|
||||
|
||||
#include "Index.h"
|
||||
#include "Node.h"
|
||||
#include "NodeListener.h"
|
||||
#include "PackageDomain.h"
|
||||
@ -71,6 +72,9 @@ public:
|
||||
Node* node);
|
||||
void RemoveNodeListener(NodeListener* listener);
|
||||
|
||||
Index* FindIndex(const char* name) const
|
||||
{ return fIndices.Lookup(name); }
|
||||
|
||||
// VFS wrappers
|
||||
status_t GetVNode(ino_t nodeID, Node*& _node);
|
||||
status_t PutVNode(ino_t nodeID);
|
||||
@ -188,6 +192,7 @@ private:
|
||||
|
||||
NodeIDHashTable fNodes;
|
||||
NodeListenerHashTable fNodeListeners;
|
||||
IndexHashTable fIndices;
|
||||
|
||||
JobList fJobQueue;
|
||||
mutex fJobQueueLock;
|
||||
|
Loading…
Reference in New Issue
Block a user