WIP towards dependency package links
* Add ResolvableFamily and DependencyFamily classes for grouping equally
named resolvables/dependencies.
* Add hash tables to PackageFSRoot to track resolvables and
dependencies. That is done in {Add,Remove}Package.
* Resolvable does now have a list of Dependency objects, the ones it
satisfies.
This commit is contained in:
@@ -15,6 +15,7 @@
|
|||||||
Dependency::Dependency(Package* package)
|
Dependency::Dependency(Package* package)
|
||||||
:
|
:
|
||||||
fPackage(package),
|
fPackage(package),
|
||||||
|
fFamily(NULL),
|
||||||
fResolvable(NULL),
|
fResolvable(NULL),
|
||||||
fName(NULL),
|
fName(NULL),
|
||||||
fVersion(NULL),
|
fVersion(NULL),
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#include <util/DoublyLinkedList.h>
|
#include <util/DoublyLinkedList.h>
|
||||||
|
|
||||||
|
|
||||||
|
class DependencyFamily;
|
||||||
class Package;
|
class Package;
|
||||||
class Resolvable;
|
class Resolvable;
|
||||||
class Version;
|
class Version;
|
||||||
@@ -34,21 +35,41 @@ public:
|
|||||||
// version is optional; object takes over
|
// version is optional; object takes over
|
||||||
// ownership
|
// ownership
|
||||||
|
|
||||||
|
void SetFamily(DependencyFamily* family)
|
||||||
|
{ fFamily = family; }
|
||||||
|
DependencyFamily* Family() const
|
||||||
|
{ return fFamily; }
|
||||||
|
|
||||||
void SetResolvable(::Resolvable* resolvable)
|
void SetResolvable(::Resolvable* resolvable)
|
||||||
{ fResolvable = resolvable; }
|
{ fResolvable = resolvable; }
|
||||||
::Resolvable* Resolvable() const
|
::Resolvable* Resolvable() const
|
||||||
{ return fResolvable; }
|
{ return fResolvable; }
|
||||||
|
|
||||||
|
const char* Name() const { return fName; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Package* fPackage;
|
Package* fPackage;
|
||||||
|
DependencyFamily* fFamily;
|
||||||
::Resolvable* fResolvable;
|
::Resolvable* fResolvable;
|
||||||
char* fName;
|
char* fName;
|
||||||
Version* fVersion;
|
Version* fVersion;
|
||||||
BPackageResolvableOperator fVersionOperator;
|
BPackageResolvableOperator fVersionOperator;
|
||||||
|
|
||||||
|
public: // conceptually package private
|
||||||
|
DoublyLinkedListLink<Dependency> fFamilyListLink;
|
||||||
|
DoublyLinkedListLink<Dependency> fResolvableListLink;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
typedef DoublyLinkedList<Dependency> DependencyList;
|
typedef DoublyLinkedList<Dependency> DependencyList;
|
||||||
|
|
||||||
|
typedef DoublyLinkedList<Dependency,
|
||||||
|
DoublyLinkedListMemberGetLink<Dependency,
|
||||||
|
&Dependency::fFamilyListLink> > FamilyDependencyList;
|
||||||
|
|
||||||
|
typedef DoublyLinkedList<Dependency,
|
||||||
|
DoublyLinkedListMemberGetLink<Dependency,
|
||||||
|
&Dependency::fResolvableListLink> > ResolvableDependencyList;
|
||||||
|
|
||||||
|
|
||||||
#endif // DEPENDENCY_H
|
#endif // DEPENDENCY_H
|
||||||
|
|||||||
@@ -0,0 +1,97 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2011, Ingo Weinhold, [email protected].
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
#ifndef DEPENDENCY_FAMILY_H
|
||||||
|
#define DEPENDENCY_FAMILY_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <util/khash.h>
|
||||||
|
#include <util/OpenHashTable.h>
|
||||||
|
|
||||||
|
#include "Dependency.h"
|
||||||
|
|
||||||
|
|
||||||
|
class DependencyFamily {
|
||||||
|
public:
|
||||||
|
void AddDependency(Dependency* dependency);
|
||||||
|
void RemoveDependency(Dependency* dependency);
|
||||||
|
|
||||||
|
const char* Name() const;
|
||||||
|
|
||||||
|
bool IsLastDependency(Dependency* dependency) const;
|
||||||
|
|
||||||
|
DependencyFamily*& HashLink() { return fHashLink; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
DependencyFamily* fHashLink;
|
||||||
|
FamilyDependencyList fDependencies;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
inline void
|
||||||
|
DependencyFamily::AddDependency(Dependency* dependency)
|
||||||
|
{
|
||||||
|
fDependencies.Add(dependency);
|
||||||
|
dependency->SetFamily(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void
|
||||||
|
DependencyFamily::RemoveDependency(Dependency* dependency)
|
||||||
|
{
|
||||||
|
dependency->SetFamily(NULL);
|
||||||
|
fDependencies.Remove(dependency);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline const char*
|
||||||
|
DependencyFamily::Name() const
|
||||||
|
{
|
||||||
|
Dependency* head = fDependencies.Head();
|
||||||
|
return head != NULL ? head->Name() : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
DependencyFamily::IsLastDependency(Dependency* dependency) const
|
||||||
|
{
|
||||||
|
return fDependencies.Head() == dependency
|
||||||
|
&& fDependencies.Tail() == dependency;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - DependencyFamilyHashDefinition
|
||||||
|
|
||||||
|
|
||||||
|
struct DependencyFamilyHashDefinition {
|
||||||
|
typedef const char* KeyType;
|
||||||
|
typedef DependencyFamily ValueType;
|
||||||
|
|
||||||
|
size_t HashKey(const char* key) const
|
||||||
|
{
|
||||||
|
return key != NULL ? hash_hash_string(key) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Hash(const DependencyFamily* value) const
|
||||||
|
{
|
||||||
|
return HashKey(value->Name());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Compare(const char* key, const DependencyFamily* value) const
|
||||||
|
{
|
||||||
|
return strcmp(value->Name(), key) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
DependencyFamily*& GetLink(DependencyFamily* value) const
|
||||||
|
{
|
||||||
|
return value->HashLink();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
typedef BOpenHashTable<DependencyFamilyHashDefinition>
|
||||||
|
DependencyFamilyHashTable;
|
||||||
|
|
||||||
|
|
||||||
|
#endif // DEPENDENCY_FAMILY_H
|
||||||
@@ -30,6 +30,7 @@ HAIKU_PACKAGE_FS_SOURCES =
|
|||||||
PackageNodeAttribute.cpp
|
PackageNodeAttribute.cpp
|
||||||
PackageSymlink.cpp
|
PackageSymlink.cpp
|
||||||
Resolvable.cpp
|
Resolvable.cpp
|
||||||
|
ResolvableFamily.cpp
|
||||||
UnpackingAttributeCookie.cpp
|
UnpackingAttributeCookie.cpp
|
||||||
UnpackingAttributeDirectoryCookie.cpp
|
UnpackingAttributeDirectoryCookie.cpp
|
||||||
UnpackingDirectory.cpp
|
UnpackingDirectory.cpp
|
||||||
|
|||||||
@@ -60,7 +60,11 @@ public:
|
|||||||
int Open();
|
int Open();
|
||||||
void Close();
|
void Close();
|
||||||
|
|
||||||
const PackageNodeList& Nodes() const { return fNodes; }
|
const PackageNodeList& Nodes() const { return fNodes; }
|
||||||
|
const ResolvableList& Resolvables() const
|
||||||
|
{ return fResolvables; }
|
||||||
|
const DependencyList& Dependencies() const
|
||||||
|
{ return fDependencies; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
mutex fLock;
|
mutex fLock;
|
||||||
|
|||||||
@@ -64,6 +64,14 @@ PackageFSRoot::Init()
|
|||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
RETURN_ERROR(error);
|
RETURN_ERROR(error);
|
||||||
|
|
||||||
|
error = fResolvables.Init();
|
||||||
|
if (error != B_OK)
|
||||||
|
RETURN_ERROR(error);
|
||||||
|
|
||||||
|
error = fDependencies.Init();
|
||||||
|
if (error != B_OK)
|
||||||
|
RETURN_ERROR(error);
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,14 +167,24 @@ PackageFSRoot::UnregisterVolume(Volume* volume)
|
|||||||
status_t
|
status_t
|
||||||
PackageFSRoot::AddPackage(Package* package)
|
PackageFSRoot::AddPackage(Package* package)
|
||||||
{
|
{
|
||||||
return fPackageLinksDirectory->AddPackage(package);
|
PackageFSRootWriteLocker writeLocker(this);
|
||||||
|
|
||||||
|
status_t error = _AddPackage(package);
|
||||||
|
if (error != B_OK) {
|
||||||
|
_RemovePackage(package);
|
||||||
|
RETURN_ERROR(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
PackageFSRoot::RemovePackage(Package* package)
|
PackageFSRoot::RemovePackage(Package* package)
|
||||||
{
|
{
|
||||||
fPackageLinksDirectory->RemovePackage(package);
|
PackageFSRootWriteLocker writeLocker(this);
|
||||||
|
|
||||||
|
_RemovePackage(package);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -209,6 +227,100 @@ PackageFSRoot::_RemoveVolume(Volume* volume)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
PackageFSRoot::_AddPackage(Package* package)
|
||||||
|
{
|
||||||
|
ResolvableDependencyList dependenciesToUpdate;
|
||||||
|
|
||||||
|
// register resolvables
|
||||||
|
for (ResolvableList::ConstIterator it
|
||||||
|
= package->Resolvables().GetIterator();
|
||||||
|
Resolvable* resolvable = it.Next();) {
|
||||||
|
if (ResolvableFamily* family
|
||||||
|
= fResolvables.Lookup(resolvable->Name())) {
|
||||||
|
family->AddResolvable(resolvable, dependenciesToUpdate);
|
||||||
|
} else {
|
||||||
|
ResolvableFamily* family = new(std::nothrow) ResolvableFamily;
|
||||||
|
if (family == NULL)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
|
family->AddResolvable(resolvable, dependenciesToUpdate);
|
||||||
|
fResolvables.Insert(family);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// register dependencies
|
||||||
|
for (DependencyList::ConstIterator it
|
||||||
|
= package->Dependencies().GetIterator();
|
||||||
|
Dependency* dependency = it.Next();) {
|
||||||
|
if (DependencyFamily* family
|
||||||
|
= fDependencies.Lookup(dependency->Name())) {
|
||||||
|
family->AddDependency(dependency);
|
||||||
|
} else {
|
||||||
|
DependencyFamily* family = new(std::nothrow) DependencyFamily;
|
||||||
|
if (family == NULL)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
|
family->AddDependency(dependency);
|
||||||
|
fDependencies.Insert(family);
|
||||||
|
}
|
||||||
|
|
||||||
|
dependenciesToUpdate.Add(dependency);
|
||||||
|
}
|
||||||
|
|
||||||
|
return fPackageLinksDirectory->AddPackage(package);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PackageFSRoot::_RemovePackage(Package* package)
|
||||||
|
{
|
||||||
|
fPackageLinksDirectory->RemovePackage(package);
|
||||||
|
|
||||||
|
// unregister dependencies
|
||||||
|
for (DependencyList::ConstIterator it
|
||||||
|
= package->Dependencies().GetIterator();
|
||||||
|
Dependency* dependency = it.Next();) {
|
||||||
|
if (DependencyFamily* family = dependency->Family()) {
|
||||||
|
if (family->IsLastDependency(dependency)) {
|
||||||
|
fDependencies.Remove(family);
|
||||||
|
family->RemoveDependency(dependency);
|
||||||
|
delete family;
|
||||||
|
} else
|
||||||
|
family->RemoveDependency(dependency);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// unregister resolvables
|
||||||
|
ResolvableDependencyList dependenciesToUpdate;
|
||||||
|
|
||||||
|
for (ResolvableList::ConstIterator it
|
||||||
|
= package->Resolvables().GetIterator();
|
||||||
|
Resolvable* resolvable = it.Next();) {
|
||||||
|
if (ResolvableFamily* family = resolvable->Family()) {
|
||||||
|
if (family->IsLastResolvable(resolvable)) {
|
||||||
|
fResolvables.Remove(family);
|
||||||
|
family->RemoveResolvable(resolvable, dependenciesToUpdate);
|
||||||
|
delete family;
|
||||||
|
} else
|
||||||
|
family->RemoveResolvable(resolvable, dependenciesToUpdate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_ResolveDependencies(dependenciesToUpdate);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PackageFSRoot::_ResolveDependencies(ResolvableDependencyList& dependencies)
|
||||||
|
{
|
||||||
|
if (dependencies.IsEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// TODO:...
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*static*/ status_t
|
/*static*/ status_t
|
||||||
PackageFSRoot::_GetOrCreateRoot(dev_t deviceID, ino_t nodeID,
|
PackageFSRoot::_GetOrCreateRoot(dev_t deviceID, ino_t nodeID,
|
||||||
PackageFSRoot*& _root)
|
PackageFSRoot*& _root)
|
||||||
|
|||||||
@@ -13,6 +13,8 @@
|
|||||||
|
|
||||||
#include <lock.h>
|
#include <lock.h>
|
||||||
|
|
||||||
|
#include "DependencyFamily.h"
|
||||||
|
#include "ResolvableFamily.h"
|
||||||
#include "Volume.h"
|
#include "Volume.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -58,6 +60,12 @@ private:
|
|||||||
status_t _AddVolume(Volume* volume);
|
status_t _AddVolume(Volume* volume);
|
||||||
void _RemoveVolume(Volume* volume);
|
void _RemoveVolume(Volume* volume);
|
||||||
|
|
||||||
|
status_t _AddPackage(Package* package);
|
||||||
|
void _RemovePackage(Package* package);
|
||||||
|
|
||||||
|
void _ResolveDependencies(
|
||||||
|
ResolvableDependencyList& dependencies);
|
||||||
|
|
||||||
static status_t _GetOrCreateRoot(dev_t deviceID, ino_t nodeID,
|
static status_t _GetOrCreateRoot(dev_t deviceID, ino_t nodeID,
|
||||||
PackageFSRoot*& _root);
|
PackageFSRoot*& _root);
|
||||||
static PackageFSRoot* _FindRootLocked(dev_t deviceID, ino_t nodeID);
|
static PackageFSRoot* _FindRootLocked(dev_t deviceID, ino_t nodeID);
|
||||||
@@ -73,6 +81,8 @@ private:
|
|||||||
VolumeList fVolumes;
|
VolumeList fVolumes;
|
||||||
Volume* fSystemVolume;
|
Volume* fSystemVolume;
|
||||||
PackageLinksDirectory* fPackageLinksDirectory;
|
PackageLinksDirectory* fPackageLinksDirectory;
|
||||||
|
ResolvableFamilyHashTable fResolvables;
|
||||||
|
DependencyFamilyHashTable fDependencies;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -11,9 +11,10 @@
|
|||||||
#include "Version.h"
|
#include "Version.h"
|
||||||
|
|
||||||
|
|
||||||
Resolvable::Resolvable(Package* package)
|
Resolvable::Resolvable(::Package* package)
|
||||||
:
|
:
|
||||||
fPackage(package),
|
fPackage(package),
|
||||||
|
fFamily(NULL),
|
||||||
fName(NULL),
|
fName(NULL),
|
||||||
fVersion(NULL)
|
fVersion(NULL)
|
||||||
{
|
{
|
||||||
@@ -38,3 +39,34 @@ Resolvable::Init(const char* name, Version* version)
|
|||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Resolvable::AddDependency(Dependency* dependency)
|
||||||
|
{
|
||||||
|
fDependencies.Add(dependency);
|
||||||
|
dependency->SetResolvable(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Resolvable::RemoveDependency(Dependency* dependency)
|
||||||
|
{
|
||||||
|
fDependencies.Remove(dependency);
|
||||||
|
dependency->SetResolvable(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Resolvable::MoveDependencies(ResolvableDependencyList& dependencies)
|
||||||
|
{
|
||||||
|
if (fDependencies.IsEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (ResolvableDependencyList::Iterator it = fDependencies.GetIterator();
|
||||||
|
Dependency* dependency = it.Next();) {
|
||||||
|
dependency->SetResolvable(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies.MoveFrom(&fDependencies);
|
||||||
|
}
|
||||||
|
|||||||
@@ -10,29 +10,55 @@
|
|||||||
|
|
||||||
#include <util/DoublyLinkedList.h>
|
#include <util/DoublyLinkedList.h>
|
||||||
|
|
||||||
|
#include "Dependency.h"
|
||||||
|
|
||||||
|
|
||||||
class Package;
|
class Package;
|
||||||
|
class ResolvableFamily;
|
||||||
class Version;
|
class Version;
|
||||||
|
|
||||||
|
|
||||||
class Resolvable : public BReferenceable,
|
class Resolvable : public BReferenceable,
|
||||||
public DoublyLinkedListLinkImpl<Resolvable> {
|
public DoublyLinkedListLinkImpl<Resolvable> {
|
||||||
public:
|
public:
|
||||||
Resolvable(Package* package);
|
Resolvable(::Package* package);
|
||||||
virtual ~Resolvable();
|
virtual ~Resolvable();
|
||||||
|
|
||||||
status_t Init(const char* name, Version* version);
|
status_t Init(const char* name, Version* version);
|
||||||
// version is optional; object takes over
|
// version is optional; object takes over
|
||||||
// ownership (even in case of error)
|
// ownership (even in case of error)
|
||||||
|
|
||||||
|
::Package* Package() const { return fPackage; }
|
||||||
|
|
||||||
|
void SetFamily(ResolvableFamily* family)
|
||||||
|
{ fFamily = family; }
|
||||||
|
ResolvableFamily* Family() const
|
||||||
|
{ return fFamily; }
|
||||||
|
|
||||||
|
const char* Name() const { return fName; }
|
||||||
|
|
||||||
|
void AddDependency(Dependency* dependency);
|
||||||
|
void RemoveDependency(Dependency* dependency);
|
||||||
|
void MoveDependencies(
|
||||||
|
ResolvableDependencyList& dependencies);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Package* fPackage;
|
::Package* fPackage;
|
||||||
|
ResolvableFamily* fFamily;
|
||||||
char* fName;
|
char* fName;
|
||||||
Version* fVersion;
|
Version* fVersion;
|
||||||
|
ResolvableDependencyList fDependencies;
|
||||||
|
|
||||||
|
public: // conceptually package private
|
||||||
|
DoublyLinkedListLink<Resolvable> fFamilyListLink;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
typedef DoublyLinkedList<Resolvable> ResolvableList;
|
typedef DoublyLinkedList<Resolvable> ResolvableList;
|
||||||
|
|
||||||
|
typedef DoublyLinkedList<Resolvable,
|
||||||
|
DoublyLinkedListMemberGetLink<Resolvable,
|
||||||
|
&Resolvable::fFamilyListLink> > FamilyResolvableList;
|
||||||
|
|
||||||
|
|
||||||
#endif // RESOLVABLE_H
|
#endif // RESOLVABLE_H
|
||||||
|
|||||||
@@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2011, Ingo Weinhold, [email protected].
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "ResolvableFamily.h"
|
||||||
|
|
||||||
|
#include "Package.h"
|
||||||
|
#include "Volume.h"
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
ResolvableFamily::AddResolvable(Resolvable* resolvable,
|
||||||
|
ResolvableDependencyList& dependenciesToUpdate)
|
||||||
|
{
|
||||||
|
// Find the insertion point in the list. We sort by mount type -- the more
|
||||||
|
// specific the higher the priority.
|
||||||
|
MountType mountType
|
||||||
|
= resolvable->Package()->Domain()->Volume()->MountType();
|
||||||
|
Resolvable* otherResolvable = NULL;
|
||||||
|
for (FamilyResolvableList::Iterator it = fResolvables.GetIterator();
|
||||||
|
(otherResolvable = it.Next()) != NULL;) {
|
||||||
|
if (otherResolvable->Package()->Domain()->Volume()->MountType()
|
||||||
|
<= mountType) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fResolvables.InsertBefore(otherResolvable, resolvable);
|
||||||
|
resolvable->SetFamily(this);
|
||||||
|
|
||||||
|
// all dependencies after the inserted resolvable potentially need to be
|
||||||
|
// updated
|
||||||
|
while ((resolvable = fResolvables.GetNext(resolvable)) != NULL)
|
||||||
|
resolvable->MoveDependencies(dependenciesToUpdate);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
ResolvableFamily::RemoveResolvable(Resolvable* resolvable,
|
||||||
|
ResolvableDependencyList& dependenciesToUpdate)
|
||||||
|
{
|
||||||
|
resolvable->SetFamily(NULL);
|
||||||
|
fResolvables.Remove(resolvable);
|
||||||
|
}
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2011, Ingo Weinhold, [email protected].
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
#ifndef RESOLVABLE_FAMILY_H
|
||||||
|
#define RESOLVABLE_FAMILY_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <util/khash.h>
|
||||||
|
#include <util/OpenHashTable.h>
|
||||||
|
|
||||||
|
#include "Resolvable.h"
|
||||||
|
|
||||||
|
|
||||||
|
class ResolvableFamily {
|
||||||
|
public:
|
||||||
|
void AddResolvable(Resolvable* resolvable,
|
||||||
|
ResolvableDependencyList&
|
||||||
|
dependenciesToUpdate);
|
||||||
|
void RemoveResolvable(Resolvable* resolvable,
|
||||||
|
ResolvableDependencyList&
|
||||||
|
dependenciesToUpdate);
|
||||||
|
|
||||||
|
const char* Name() const;
|
||||||
|
|
||||||
|
bool IsLastResolvable(Resolvable* resolvable) const;
|
||||||
|
|
||||||
|
ResolvableFamily*& HashLink() { return fHashLink; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
ResolvableFamily* fHashLink;
|
||||||
|
FamilyResolvableList fResolvables;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
inline const char*
|
||||||
|
ResolvableFamily::Name() const
|
||||||
|
{
|
||||||
|
Resolvable* head = fResolvables.Head();
|
||||||
|
return head != NULL ? head->Name() : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
ResolvableFamily::IsLastResolvable(Resolvable* resolvable) const
|
||||||
|
{
|
||||||
|
return fResolvables.Head() == resolvable
|
||||||
|
&& fResolvables.Tail() == resolvable;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - ResolvableFamilyHashDefinition
|
||||||
|
|
||||||
|
|
||||||
|
struct ResolvableFamilyHashDefinition {
|
||||||
|
typedef const char* KeyType;
|
||||||
|
typedef ResolvableFamily ValueType;
|
||||||
|
|
||||||
|
size_t HashKey(const char* key) const
|
||||||
|
{
|
||||||
|
return key != NULL ? hash_hash_string(key) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Hash(const ResolvableFamily* value) const
|
||||||
|
{
|
||||||
|
return HashKey(value->Name());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Compare(const char* key, const ResolvableFamily* value) const
|
||||||
|
{
|
||||||
|
return strcmp(value->Name(), key) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ResolvableFamily*& GetLink(ResolvableFamily* value) const
|
||||||
|
{
|
||||||
|
return value->HashLink();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
typedef BOpenHashTable<ResolvableFamilyHashDefinition>
|
||||||
|
ResolvableFamilyHashTable;
|
||||||
|
|
||||||
|
|
||||||
|
#endif // RESOLVABLE_FAMILY_H
|
||||||
Reference in New Issue
Block a user