WIP: Create empty package links directories
* Rename PackageFamily to PackageLinkDirectory and derive from Directory. * PackageLinksDirectory: Add the PackageLinkDirectory objects as children and remove the no longer needed hash table (we use the Directory's child hash table).
This commit is contained in:
parent
05d7d4818e
commit
4031a32acc
@ -20,10 +20,10 @@ HAIKU_PACKAGE_FS_SOURCES =
|
||||
Package.cpp
|
||||
PackageDirectory.cpp
|
||||
PackageDomain.cpp
|
||||
PackageFamily.cpp
|
||||
PackageFile.cpp
|
||||
PackageFSRoot.cpp
|
||||
PackageLeafNode.cpp
|
||||
PackageLinkDirectory.cpp
|
||||
PackageLinksDirectory.cpp
|
||||
PackageNode.cpp
|
||||
PackageNodeAttribute.cpp
|
||||
|
@ -25,7 +25,7 @@ Package::Package(PackageDomain* domain, dev_t deviceID, ino_t nodeID)
|
||||
fFileName(NULL),
|
||||
fName(NULL),
|
||||
fVersion(NULL),
|
||||
fFamily(NULL),
|
||||
fLinkDirectory(NULL),
|
||||
fFD(-1),
|
||||
fOpenCount(0),
|
||||
fNodeID(nodeID),
|
||||
|
@ -20,7 +20,7 @@
|
||||
|
||||
|
||||
class PackageDomain;
|
||||
class PackageFamily;
|
||||
class PackageLinkDirectory;
|
||||
class Version;
|
||||
|
||||
|
||||
@ -44,10 +44,11 @@ public:
|
||||
::Version* Version() const
|
||||
{ return fVersion; }
|
||||
|
||||
void SetFamily(PackageFamily* family)
|
||||
{ fFamily = family; }
|
||||
PackageFamily* Family() const
|
||||
{ return fFamily; }
|
||||
void SetLinkDirectory(
|
||||
PackageLinkDirectory* linkDirectory)
|
||||
{ fLinkDirectory = linkDirectory; }
|
||||
PackageLinkDirectory* LinkDirectory() const
|
||||
{ return fLinkDirectory; }
|
||||
|
||||
Package*& FileNameHashTableNext()
|
||||
{ return fFileNameHashTableNext; }
|
||||
@ -67,7 +68,7 @@ private:
|
||||
char* fFileName;
|
||||
char* fName;
|
||||
::Version* fVersion;
|
||||
PackageFamily* fFamily;
|
||||
PackageLinkDirectory* fLinkDirectory;
|
||||
int fFD;
|
||||
uint32 fOpenCount;
|
||||
Package* fFileNameHashTableNext;
|
||||
|
@ -1,78 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include "PackageFamily.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "DebugSupport.h"
|
||||
#include "Version.h"
|
||||
|
||||
|
||||
PackageFamily::PackageFamily()
|
||||
:
|
||||
fName(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
PackageFamily::~PackageFamily()
|
||||
{
|
||||
while (Package* package = fPackages.RemoveHead())
|
||||
package->SetFamily(NULL);
|
||||
|
||||
free(fName);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
PackageFamily::Init(Package* package)
|
||||
{
|
||||
// compute the allocation size needed for the versioned name
|
||||
size_t nameLength = strlen(package->Name());
|
||||
size_t size = nameLength + 1;
|
||||
|
||||
Version* version = package->Version();
|
||||
if (version != NULL) {
|
||||
size += 1 + version->ToString(NULL, 0);
|
||||
// + 1 for the '-'
|
||||
}
|
||||
|
||||
// allocate the name and compose it
|
||||
fName = (char*)malloc(size);
|
||||
if (fName == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
memcpy(fName, package->Name(), nameLength + 1);
|
||||
if (version != NULL) {
|
||||
fName[nameLength] = '-';
|
||||
version->ToString(fName + nameLength + 1, size - nameLength - 1);
|
||||
}
|
||||
|
||||
// add the package
|
||||
AddPackage(package);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PackageFamily::AddPackage(Package* package)
|
||||
{
|
||||
fPackages.Add(package);
|
||||
package->SetFamily(this);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PackageFamily::RemovePackage(Package* package)
|
||||
{
|
||||
ASSERT(package->Family() == this);
|
||||
|
||||
package->SetFamily(NULL);
|
||||
fPackages.Remove(package);
|
||||
}
|
@ -1,71 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef PACKAGE_FAMILY_H
|
||||
#define PACKAGE_FAMILY_H
|
||||
|
||||
|
||||
#include <Referenceable.h>
|
||||
|
||||
#include "Package.h"
|
||||
|
||||
|
||||
/*! A set of equally named and versioned packages.
|
||||
This should only happen when the same package is installed in multiple
|
||||
domains (e.g. common and home).
|
||||
*/
|
||||
class PackageFamily {
|
||||
public:
|
||||
PackageFamily();
|
||||
~PackageFamily();
|
||||
|
||||
status_t Init(Package* package);
|
||||
|
||||
const char* Name() const { return fName; }
|
||||
|
||||
void AddPackage(Package* package);
|
||||
void RemovePackage(Package* package);
|
||||
|
||||
bool IsEmpty() const
|
||||
{ return fPackages.IsEmpty(); }
|
||||
|
||||
PackageFamily*& HashNext() { return fHashNext; }
|
||||
|
||||
private:
|
||||
PackageFamily* fHashNext;
|
||||
char* fName;
|
||||
PackageList fPackages;
|
||||
};
|
||||
|
||||
|
||||
struct PackageFamilyHashDefinition {
|
||||
typedef const char* KeyType;
|
||||
typedef PackageFamily ValueType;
|
||||
|
||||
size_t HashKey(const char* key) const
|
||||
{
|
||||
return hash_hash_string(key);
|
||||
}
|
||||
|
||||
size_t Hash(const PackageFamily* value) const
|
||||
{
|
||||
return HashKey(value->Name());
|
||||
}
|
||||
|
||||
bool Compare(const char* key, const PackageFamily* value) const
|
||||
{
|
||||
return strcmp(value->Name(), key) == 0;
|
||||
}
|
||||
|
||||
PackageFamily*& GetLink(PackageFamily* value) const
|
||||
{
|
||||
return value->HashNext();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
typedef BOpenHashTable<PackageFamilyHashDefinition> PackageFamilyHashTable;
|
||||
|
||||
|
||||
#endif // PACKAGE_FAMILY_H
|
@ -0,0 +1,151 @@
|
||||
/*
|
||||
* Copyright 2011, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include "PackageLinkDirectory.h"
|
||||
|
||||
#include <AutoDeleter.h>
|
||||
|
||||
#include "EmptyAttributeDirectoryCookie.h"
|
||||
#include "DebugSupport.h"
|
||||
#include "Utils.h"
|
||||
#include "Version.h"
|
||||
|
||||
|
||||
PackageLinkDirectory::PackageLinkDirectory()
|
||||
:
|
||||
Directory(0)
|
||||
// the ID needs to be assigned later, when added to a volume
|
||||
{
|
||||
get_real_time(fModifiedTime);
|
||||
}
|
||||
|
||||
|
||||
PackageLinkDirectory::~PackageLinkDirectory()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
PackageLinkDirectory::Init(Directory* parent, Package* package)
|
||||
{
|
||||
// compute the allocation size needed for the versioned name
|
||||
size_t nameLength = strlen(package->Name());
|
||||
size_t size = nameLength + 1;
|
||||
|
||||
Version* version = package->Version();
|
||||
if (version != NULL) {
|
||||
size += 1 + version->ToString(NULL, 0);
|
||||
// + 1 for the '-'
|
||||
}
|
||||
|
||||
// allocate the name and compose it
|
||||
char* name = (char*)malloc(size);
|
||||
if (name == NULL)
|
||||
return B_NO_MEMORY;
|
||||
MemoryDeleter nameDeleter(name);
|
||||
|
||||
memcpy(name, package->Name(), nameLength + 1);
|
||||
if (version != NULL) {
|
||||
name[nameLength] = '-';
|
||||
version->ToString(name + nameLength + 1, size - nameLength - 1);
|
||||
}
|
||||
|
||||
// init the directory/node
|
||||
status_t error = Init(parent, name);
|
||||
// TODO: This copies the name unnecessarily!
|
||||
if (error != B_OK)
|
||||
RETURN_ERROR(error);
|
||||
|
||||
// add the package
|
||||
AddPackage(package);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
PackageLinkDirectory::Init(Directory* parent, const char* name)
|
||||
{
|
||||
return Directory::Init(parent, name);
|
||||
}
|
||||
|
||||
|
||||
mode_t
|
||||
PackageLinkDirectory::Mode() const
|
||||
{
|
||||
return S_IFDIR | S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
|
||||
}
|
||||
|
||||
|
||||
uid_t
|
||||
PackageLinkDirectory::UserID() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
gid_t
|
||||
PackageLinkDirectory::GroupID() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
timespec
|
||||
PackageLinkDirectory::ModifiedTime() const
|
||||
{
|
||||
return fModifiedTime;
|
||||
}
|
||||
|
||||
|
||||
off_t
|
||||
PackageLinkDirectory::FileSize() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
PackageLinkDirectory::OpenAttributeDirectory(
|
||||
AttributeDirectoryCookie*& _cookie)
|
||||
{
|
||||
AttributeDirectoryCookie* cookie
|
||||
= new(std::nothrow) EmptyAttributeDirectoryCookie;
|
||||
if (cookie == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
_cookie = cookie;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
PackageLinkDirectory::OpenAttribute(const char* name, int openMode,
|
||||
AttributeCookie*& _cookie)
|
||||
{
|
||||
return B_ENTRY_NOT_FOUND;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PackageLinkDirectory::AddPackage(Package* package)
|
||||
{
|
||||
// TODO: Add in priority order!
|
||||
fPackages.Add(package);
|
||||
package->SetLinkDirectory(this);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PackageLinkDirectory::RemovePackage(Package* package)
|
||||
{
|
||||
|
||||
ASSERT(package->LinkDirectory() == this);
|
||||
|
||||
package->SetLinkDirectory(NULL);
|
||||
fPackages.Remove(package);
|
||||
// TODO: Check whether that was the top priority package!
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2011, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef PACKAGE_LINK_DIRECTORY_H
|
||||
#define PACKAGE_LINK_DIRECTORY_H
|
||||
|
||||
|
||||
#include "Directory.h"
|
||||
#include "Package.h"
|
||||
|
||||
|
||||
class PackageLinkDirectory : public Directory {
|
||||
public:
|
||||
PackageLinkDirectory();
|
||||
virtual ~PackageLinkDirectory();
|
||||
|
||||
status_t Init(Directory* parent, Package* package);
|
||||
virtual status_t Init(Directory* parent, const char* name);
|
||||
|
||||
virtual mode_t Mode() const;
|
||||
virtual uid_t UserID() const;
|
||||
virtual gid_t GroupID() const;
|
||||
virtual timespec ModifiedTime() const;
|
||||
virtual off_t FileSize() const;
|
||||
|
||||
virtual status_t OpenAttributeDirectory(
|
||||
AttributeDirectoryCookie*& _cookie);
|
||||
virtual status_t OpenAttribute(const char* name, int openMode,
|
||||
AttributeCookie*& _cookie);
|
||||
|
||||
void AddPackage(Package* package);
|
||||
void RemovePackage(Package* package);
|
||||
|
||||
bool IsEmpty() const
|
||||
{ return fPackages.IsEmpty(); }
|
||||
|
||||
private:
|
||||
timespec fModifiedTime;
|
||||
PackageList fPackages;
|
||||
};
|
||||
|
||||
|
||||
#endif // PACKAGE_LINK_DIRECTORY_H
|
@ -10,6 +10,7 @@
|
||||
|
||||
#include "EmptyAttributeDirectoryCookie.h"
|
||||
#include "DebugSupport.h"
|
||||
#include "PackageLinkDirectory.h"
|
||||
#include "Utils.h"
|
||||
|
||||
|
||||
@ -30,10 +31,6 @@ PackageLinksDirectory::~PackageLinksDirectory()
|
||||
status_t
|
||||
PackageLinksDirectory::Init(Directory* parent, const char* name)
|
||||
{
|
||||
status_t error = fPackageFamilies.Init();
|
||||
if (error != B_OK)
|
||||
RETURN_ERROR(error);
|
||||
|
||||
return Directory::Init(parent, name);
|
||||
}
|
||||
|
||||
@ -98,26 +95,32 @@ PackageLinksDirectory::OpenAttribute(const char* name, int openMode,
|
||||
status_t
|
||||
PackageLinksDirectory::AddPackage(Package* package)
|
||||
{
|
||||
// Create a package family -- there might already be one, but since that's
|
||||
// unlikely, we don't bother to check and recheck later.
|
||||
PackageFamily* packageFamily = new(std::nothrow) PackageFamily;
|
||||
if (packageFamily == NULL)
|
||||
// Create a package link directory -- there might already be one, but since
|
||||
// that's unlikely, we don't bother to check and recheck later.
|
||||
PackageLinkDirectory* linkDirectory
|
||||
= new(std::nothrow) PackageLinkDirectory;
|
||||
if (linkDirectory == NULL)
|
||||
return B_NO_MEMORY;
|
||||
ObjectDeleter<PackageFamily> packageFamilyDeleter(packageFamily);
|
||||
BReference<PackageLinkDirectory> linkDirectoryReference(linkDirectory,
|
||||
true);
|
||||
|
||||
status_t error = packageFamily->Init(package);
|
||||
status_t error = linkDirectory->Init(this, package);
|
||||
if (error != B_OK)
|
||||
RETURN_ERROR(error);
|
||||
|
||||
// add the family
|
||||
// add the link directory
|
||||
NodeWriteLocker writeLocker(this);
|
||||
if (PackageFamily* otherPackageFamily
|
||||
= fPackageFamilies.Lookup(packageFamily->Name())) {
|
||||
packageFamily->RemovePackage(package);
|
||||
packageFamily = otherPackageFamily;
|
||||
packageFamily->AddPackage(package);
|
||||
if (Node* child = FindChild(linkDirectory->Name())) {
|
||||
PackageLinkDirectory* otherLinkDirectory
|
||||
= dynamic_cast<PackageLinkDirectory*>(child);
|
||||
if (otherLinkDirectory != NULL)
|
||||
RETURN_ERROR(B_BAD_VALUE);
|
||||
|
||||
linkDirectory->RemovePackage(package);
|
||||
linkDirectory = otherLinkDirectory;
|
||||
linkDirectory->AddPackage(package);
|
||||
} else
|
||||
fPackageFamilies.Insert(packageFamilyDeleter.Detach());
|
||||
AddChild(linkDirectory);
|
||||
|
||||
// TODO:...
|
||||
|
||||
@ -128,18 +131,20 @@ PackageLinksDirectory::AddPackage(Package* package)
|
||||
void
|
||||
PackageLinksDirectory::RemovePackage(Package* package)
|
||||
{
|
||||
NodeWriteLocker writeLocker(this);
|
||||
|
||||
PackageFamily* packageFamily = package->Family();
|
||||
if (packageFamily == NULL)
|
||||
// get the package's link directory and remove the package from it
|
||||
PackageLinkDirectory* linkDirectory = package->LinkDirectory();
|
||||
if (linkDirectory == NULL)
|
||||
return;
|
||||
|
||||
packageFamily->RemovePackage(package);
|
||||
BReference<PackageLinkDirectory> linkDirectoryReference(linkDirectory);
|
||||
|
||||
if (packageFamily->IsEmpty()) {
|
||||
fPackageFamilies.Remove(packageFamily);
|
||||
delete packageFamily;
|
||||
}
|
||||
NodeWriteLocker writeLocker(this);
|
||||
|
||||
linkDirectory->RemovePackage(package);
|
||||
|
||||
// if empty, remove the link directory itself
|
||||
if (linkDirectory->IsEmpty())
|
||||
RemoveChild(linkDirectory);
|
||||
|
||||
// TODO:...
|
||||
}
|
||||
|
@ -7,7 +7,9 @@
|
||||
|
||||
|
||||
#include "Directory.h"
|
||||
#include "PackageFamily.h"
|
||||
|
||||
|
||||
class Package;
|
||||
|
||||
|
||||
class PackageLinksDirectory : public Directory {
|
||||
@ -33,7 +35,6 @@ public:
|
||||
|
||||
private:
|
||||
timespec fModifiedTime;
|
||||
PackageFamilyHashTable fPackageFamilies;
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user