Got rid of the List template class in the disk device manager source dir. Instead we use the Vector based Kernel Utils classes now. Various related changes.

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@3810 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold 2003-07-02 16:29:33 +00:00
parent aabf9e6b16
commit 5b489f6f16
8 changed files with 157 additions and 474 deletions

View File

@ -4,7 +4,6 @@
#define _K_DISK_DEVICE_MANAGER_H
#include "disk_device_manager.h"
#include "List.h"
#include "Locker.h"
namespace BPrivate {
@ -58,7 +57,7 @@ public:
// manager must be locked
int32 CountDevices();
KDiskDevice *DeviceAt(int32 index);
KDiskDevice *NextDevice(int32 *cookie);
bool PartitionAdded(KPartition *partition); // implementation internal
bool PartitionRemoved(KPartition *partition); //
@ -82,7 +81,7 @@ public:
KDiskSystem *DiskSystemWithName(const char *name);
KDiskSystem *DiskSystemWithID(disk_system_id id);
int32 CountDiskSystems();
KDiskSystem *DiskSystemAt(int32 index);
KDiskSystem *NextDiskSystem(int32 *cookie);
KDiskSystem *LoadDiskSystem(disk_system_id id);
KDiskSystem *LoadNextDiskSystem(int32 *cookie);
@ -106,11 +105,16 @@ private:
status_t _ScanDevice(KDiskDevice *device);
status_t _ScanPartition(KPartition *partition);
struct DeviceMap;
struct DiskSystemMap;
struct PartitionMap;
struct PartitionSet;
BLocker fLock;
List<KDiskDevice*> fDevices; // TODO: Optimize!
List<KPartition*> fPartitions; //
List<KDiskSystem*> fDiskSystems; //
List<KPartition*> fObsoletePartitions; //
DeviceMap *fDevices;
PartitionMap *fPartitions;
DiskSystemMap *fDiskSystems;
PartitionSet *fObsoletePartitions;
static KDiskDeviceManager *fDefaultManager;
};

View File

@ -3,8 +3,9 @@
#ifndef _K_DISK_DEVICE_PARTITION_H
#define _K_DISK_DEVICE_PARTITION_H
#include <Vector.h>
#include "disk_device_manager.h"
#include "List.h"
// partition flags
// TODO: move to another header (must be accessible from userland API impl.)
@ -164,8 +165,10 @@ private:
static int32 _NextID();
protected:
typedef Vector<KPartition*> PartitionVector;
partition_data fPartitionData;
List<KPartition*> fChildren;
PartitionVector fChildren;
KDiskDevice *fDevice;
KPartition *fParent;
KDiskSystem *fDiskSystem;

View File

@ -5,6 +5,7 @@ SEARCH_SOURCE += [ FDirName $(OBOS_TOP) src kits storage ] ;
# DiskDeviceTypes.cpp
UsePrivateHeaders [ FDirName kernel disk_device_manager ] ;
UsePrivateHeaders [ FDirName kernel util ] ;
UsePrivateHeaders [ FDirName shared ] ;
UsePrivateHeaders [ FDirName storage ] ;
UseHeaders [ FDirName $(OBOS_TOP) src tests kits storage virtualdrive ] ;

View File

@ -8,6 +8,9 @@
#include <string.h>
#include <sys/stat.h>
#include <VectorMap.h>
#include <VectorSet.h>
#include "KDiskDevice.h"
#include "KDiskDeviceManager.h"
#include "KDiskDeviceUtils.h"
@ -30,14 +33,56 @@ using BPrivate::DiskDevice::KDiskDeviceJobQueue;
static const char *kPartitioningSystemPrefix = "partitioning_systems";
static const char *kFileSystemPrefix = "file_systems";
// GetPartitionID
struct GetPartitionID {
inline partition_id operator()(const KPartition *partition) const
{
return partition->ID();
}
};
// GetDiskSystemID
struct GetDiskSystemID {
inline disk_system_id operator()(const KDiskSystem *system) const
{
return system->ID();
}
};
// PartitionMap
struct KDiskDeviceManager::PartitionMap : VectorMap<partition_id, KPartition*,
VectorMapEntryStrategy::ImplicitKey<partition_id, KPartition*,
GetPartitionID> > {
};
// DeviceMap
struct KDiskDeviceManager::DeviceMap : VectorMap<partition_id, KDiskDevice*,
VectorMapEntryStrategy::ImplicitKey<partition_id, KDiskDevice*,
GetPartitionID> > {
};
// DiskSystemMap
struct KDiskDeviceManager::DiskSystemMap : VectorMap<disk_system_id,
KDiskSystem*,
VectorMapEntryStrategy::ImplicitKey<disk_system_id, KDiskSystem*,
GetDiskSystemID> > {
};
// PartitionSet
struct KDiskDeviceManager::PartitionSet : VectorSet<KPartition*> {
};
// constructor
KDiskDeviceManager::KDiskDeviceManager()
: fLock("disk device manager"),
fDevices(20),
fPartitions(100),
fDiskSystems(20),
fObsoletePartitions(20)
fDevices(new(nothrow) DeviceMap),
fPartitions(new(nothrow) PartitionMap),
fDiskSystems(new(nothrow) DiskSystemMap),
fObsoletePartitions(new(nothrow) PartitionSet)
{
if (InitCheck() != B_OK)
return;
// add partitioning systems
if (void *list = open_module_list(kPartitioningSystemPrefix)) {
char moduleName[B_PATH_NAME_LENGTH];
@ -68,41 +113,44 @@ DBG(OUT("number of disk systems: %ld\n", CountDiskSystems()));
KDiskDeviceManager::~KDiskDeviceManager()
{
// remove all devices
int32 count = CountDevices();
for (int32 i = count - 1; i >= 0; i--) {
if (KDiskDevice *device = DeviceAt(i)) {
PartitionRegistrar _(device);
_RemoveDevice(device);
}
for (int32 cookie = 0; KDiskDevice *device = NextDevice(&cookie);) {
PartitionRegistrar _(device);
_RemoveDevice(device);
}
// some sanity checks
if (fPartitions.CountItems() > 0) {
if (fPartitions->Count() > 0) {
DBG(OUT("WARNING: There are still %ld unremoved partitions!\n",
fPartitions.CountItems()));
fPartitions->Count()));
}
if (fObsoletePartitions.CountItems() > 0) {
if (fObsoletePartitions->Count() > 0) {
DBG(OUT("WARNING: There are still %ld obsolete partitions!\n",
fObsoletePartitions.CountItems()));
fObsoletePartitions->Count()));
}
// remove all disk systems
count = CountDiskSystems();
for (int32 i = count - 1; i >= 0; i--) {
if (KDiskSystem *diskSystem = DiskSystemAt(i)) {
fDiskSystems.RemoveItem(i);
if (diskSystem->IsLoaded()) {
DBG(OUT("WARNING: Disk system `%s' (%ld) is still loaded!\n",
diskSystem->Name(), diskSystem->ID()));
} else
delete diskSystem;
}
for (int32 cookie = 0;
KDiskSystem *diskSystem = NextDiskSystem(&cookie); ) {
fDiskSystems->Remove(diskSystem->ID());
if (diskSystem->IsLoaded()) {
DBG(OUT("WARNING: Disk system `%s' (%ld) is still loaded!\n",
diskSystem->Name(), diskSystem->ID()));
} else
delete diskSystem;
}
// delete the containers
delete fPartitions;
delete fDevices;
delete fDiskSystems;
delete fObsoletePartitions;
}
// InitCheck
status_t
KDiskDeviceManager::InitCheck() const
{
return B_OK;
if (!fPartitions || !fDevices || !fDiskSystems || !fObsoletePartitions)
return B_NO_MEMORY;
return (fLock.Sem() >= 0 ? B_OK : fLock.Sem());
}
// CreateDefault
@ -158,7 +206,7 @@ KDiskDevice *
KDiskDeviceManager::FindDevice(const char *path, bool noShadow)
{
// TODO: Handle shadows correctly!
for (int32 i = 0; KDiskDevice *device = fDevices.ItemAt(i); i++) {
for (int32 cookie = 0; KDiskDevice *device = NextDevice(&cookie); ) {
if (device->Path() && !strcmp(path, device->Path()))
return device;
}
@ -181,7 +229,10 @@ KDiskDeviceManager::FindPartition(const char *path, bool noShadow)
{
// TODO: Handle shadows correctly!
// TODO: Optimize!
for (int32 i = 0; KPartition *partition = fPartitions.ItemAt(i); i++) {
for (PartitionMap::Iterator it = fPartitions->Begin();
it != fPartitions->End();
++it) {
KPartition *partition = it->Value();
char partitionPath[B_PATH_NAME_LENGTH];
if (partition->GetPath(partitionPath) == B_OK
&& !strcmp(path, partitionPath)) {
@ -196,10 +247,9 @@ KPartition *
KDiskDeviceManager::FindPartition(partition_id id, bool noShadow)
{
// TODO: Handle shadows correctly!
for (int32 i = 0; KPartition *partition = fPartitions.ItemAt(i); i++) {
if (partition->ID() == id)
return partition;
}
PartitionMap::Iterator it = fPartitions->Find(id);
if (it != fPartitions->End())
return it->Value();
return NULL;
}
@ -208,7 +258,7 @@ KFileDiskDevice *
KDiskDeviceManager::FindFileDevice(const char *filePath, bool noShadow)
{
// TODO: Handle shadows correctly!
for (int32 i = 0; KDiskDevice *device = fDevices.ItemAt(i); i++) {
for (int32 cookie = 0; KDiskDevice *device = NextDevice(&cookie); ) {
KFileDiskDevice *fileDevice = dynamic_cast<KFileDiskDevice*>(device);
if (fileDevice && fileDevice->FilePath()
&& !strcmp(filePath, fileDevice->FilePath())) {
@ -253,14 +303,9 @@ KDiskDeviceManager::RegisterNextDevice(int32 *cookie)
if (!cookie)
return NULL;
if (ManagerLocker locker = this) {
// TODO: This loop assumes that the device list is ordered. Make sure
// that this is really the case.
for (int32 i = 0; KDiskDevice *device = fDevices.ItemAt(i); i++) {
if (device->ID() >= *cookie) {
device->Register();
*cookie = device->ID() + 1;
return device;
}
if (KDiskDevice *device = NextDevice(cookie)) {
device->Register();
return device;
}
}
return NULL;
@ -361,25 +406,29 @@ KDiskDeviceManager::DeleteFileDevice(const char *filePath)
int32
KDiskDeviceManager::CountDevices()
{
if (ManagerLocker locker = this)
return fDevices.CountItems();
return 0;
return fDevices->Count();
}
// DiskAt
// NextDevice
KDiskDevice *
KDiskDeviceManager::DeviceAt(int32 index)
KDiskDeviceManager::NextDevice(int32 *cookie)
{
if (ManagerLocker locker = this)
return fDevices.ItemAt(index);
return 0;
if (!cookie)
return NULL;
DeviceMap::Iterator it = fDevices->FindClose(*cookie, false);
if (it != fDevices->End()) {
KDiskDevice *device = it->Value();
*cookie = device->ID() + 1;
return device;
}
return NULL;
}
// PartitionAdded
bool
KDiskDeviceManager::PartitionAdded(KPartition *partition)
{
return (partition && fPartitions.AddItem(partition));
return (partition && fPartitions->Put(partition->ID(), partition) == B_OK);
}
// PartitionRemoved
@ -387,10 +436,10 @@ bool
KDiskDeviceManager::PartitionRemoved(KPartition *partition)
{
if (partition && partition->PrepareForRemoval()
&& fPartitions.RemoveItem(partition)) {
&& fPartitions->Remove(partition->ID())) {
// If adding the partition to the obsolete list fails (due to lack
// of memory), we can't do anything about it. We will leak memory then.
fObsoletePartitions.AddItem(partition);
fObsoletePartitions->Insert(partition);
partition->MarkObsolete();
return true;
}
@ -404,7 +453,7 @@ KDiskDeviceManager::DeletePartition(KPartition *partition)
if (partition && partition->IsObsolete()
&& partition->CountReferences() == 0
&& partition->PrepareForDeletion()
&& fObsoletePartitions.RemoveItem(partition)) {
&& fObsoletePartitions->Remove(partition)) {
delete partition;
return true;
}
@ -463,7 +512,8 @@ KDiskDeviceManager::JobQueueAt(int32 index)
KDiskSystem *
KDiskDeviceManager::DiskSystemWithName(const char *name)
{
for (int32 i = 0; KDiskSystem *diskSystem = fDiskSystems.ItemAt(i); i++) {
for (int32 cookie = 0;
KDiskSystem *diskSystem = NextDiskSystem(&cookie); ) {
if (!strcmp(name, diskSystem->Name()))
return diskSystem;
}
@ -474,10 +524,9 @@ KDiskDeviceManager::DiskSystemWithName(const char *name)
KDiskSystem *
KDiskDeviceManager::DiskSystemWithID(disk_system_id id)
{
for (int32 i = 0; KDiskSystem *diskSystem = fDiskSystems.ItemAt(i); i++) {
if (diskSystem->ID() == id)
return diskSystem;
}
DiskSystemMap::Iterator it = fDiskSystems->Find(id);
if (it != fDiskSystems->End())
return it->Value();
return NULL;
}
@ -485,14 +534,22 @@ KDiskDeviceManager::DiskSystemWithID(disk_system_id id)
int32
KDiskDeviceManager::CountDiskSystems()
{
return fDiskSystems.CountItems();
return fDiskSystems->Count();
}
// DiskSystemAt
// NextDiskSystem
KDiskSystem *
KDiskDeviceManager::DiskSystemAt(int32 index)
KDiskDeviceManager::NextDiskSystem(int32 *cookie)
{
return fDiskSystems.ItemAt(index);
if (!cookie)
return NULL;
DiskSystemMap::Iterator it = fDiskSystems->FindClose(*cookie, false);
if (it != fDiskSystems->End()) {
KDiskSystem *diskSystem = it->Value();
*cookie = diskSystem->ID() + 1;
return diskSystem;
}
return NULL;
}
// LoadDiskSystem
@ -517,12 +574,10 @@ KDiskDeviceManager::LoadNextDiskSystem(int32 *cookie)
if (ManagerLocker locker = this) {
// TODO: This loop assumes that the disk system list is ordered.
// Make sure that this is really the case.
for (int32 i = 0; KDiskSystem *diskSystem = DiskSystemAt(i); i++) {
if (diskSystem->ID() >= *cookie) {
if (diskSystem->Load() == B_OK) {
*cookie = diskSystem->ID() + 1;
return diskSystem;
}
if (KDiskSystem *diskSystem = NextDiskSystem(cookie)) {
if (diskSystem->Load() == B_OK) {
*cookie = diskSystem->ID() + 1;
return diskSystem;
}
}
}
@ -583,8 +638,8 @@ DBG(OUT("KDiskDeviceManager::_AddDiskSystem(%s)\n", diskSystem->Name()));
status_t error = diskSystem->Init();
if (error != B_OK)
DBG(OUT(" initialization failed: %s\n", strerror(error)));
if (error == B_OK && !fDiskSystems.AddItem(diskSystem))
error = B_NO_MEMORY;
if (error == B_OK)
error = fDiskSystems->Put(diskSystem->ID(), diskSystem);
if (error != B_OK)
delete diskSystem;
DBG(OUT("KDiskDeviceManager::_AddDiskSystem() done: %s\n", strerror(error)));
@ -597,7 +652,7 @@ KDiskDeviceManager::_AddDevice(KDiskDevice *device)
{
if (!device || !PartitionAdded(device))
return false;
if (fDevices.AddItem(device))
if (fDevices->Put(device->ID(), device) == B_OK)
return true;
PartitionRemoved(device);
return false;
@ -607,7 +662,8 @@ KDiskDeviceManager::_AddDevice(KDiskDevice *device)
bool
KDiskDeviceManager::_RemoveDevice(KDiskDevice *device)
{
return (device && fDevices.RemoveItem(device) && PartitionRemoved(device));
return (device && fDevices->Remove(device->ID())
&& PartitionRemoved(device));
}
// _Scan

View File

@ -562,10 +562,11 @@ KPartition::AddChild(KPartition *partition, int32 index)
// add partition
KDiskDeviceManager *manager = KDiskDeviceManager::Default();
if (ManagerLocker locker = manager) {
if (!fChildren.AddItem(partition, index))
return B_NO_MEMORY;
status_t error = fChildren.Insert(partition, index);
if (error != B_OK)
return error;
if (!manager->PartitionAdded(partition)) {
fChildren.RemoveItem(index);
fChildren.Erase(index);
return B_NO_MEMORY;
}
partition->SetIndex(index);
@ -609,10 +610,10 @@ KPartition::RemoveChild(int32 index)
return false;
KDiskDeviceManager *manager = KDiskDeviceManager::Default();
if (ManagerLocker locker = manager) {
KPartition *partition = fChildren.ItemAt(index);
KPartition *partition = fChildren.ElementAt(index);
PartitionRegistrar _(partition);
if (!partition || !manager->PartitionRemoved(partition)
|| !fChildren.RemoveItem(index)) {
|| !fChildren.Erase(index)) {
return false;
}
_UpdateChildIndices(index + 1);
@ -653,7 +654,8 @@ KPartition::RemoveAllChildren()
KPartition *
KPartition::ChildAt(int32 index) const
{
return fChildren.ItemAt(index);
return (index >= 0 && index < fChildren.Count()
? fChildren.ElementAt(index) : NULL);
}
// CountChildren
@ -789,8 +791,8 @@ KPartition::Dump(bool deep, int32 level)
void
KPartition::_UpdateChildIndices(int32 index)
{
for (int32 i = index; KPartition *child = fChildren.ItemAt(i); i++)
child->SetIndex(index);
for (int32 i = index; i < fChildren.Count(); i++)
fChildren.ElementAt(i)->SetIndex(i);
}
// _NextID

View File

@ -1,385 +0,0 @@
// List.h
//
// Copyright (c) 2003, Ingo Weinhold (bonefish@cs.tu-berlin.de)
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// Except as contained in this notice, the name of a copyright holder shall
// not be used in advertising or otherwise to promote the sale, use or other
// dealings in this Software without prior written authorization of the
// copyright holder.
#ifndef LIST_H
#define LIST_H
#include <new.h>
#include <stdlib.h>
#include <string.h>
#include <SupportDefs.h>
template<typename ITEM>
class DefaultDefaultItemCreator {
public:
static inline ITEM GetItem() { return ITEM(0); }
};
/*!
\class List
\brief A generic list implementation.
*/
template<typename ITEM,
typename DEFAULT_ITEM_SUPPLIER = DefaultDefaultItemCreator<ITEM> >
class List {
public:
typedef ITEM item_t;
typedef List list_t;
private:
static item_t sDefaultItem;
static const size_t kDefaultChunkSize = 10;
static const size_t kMaximalChunkSize = 1024 * 1024;
public:
List(size_t chunkSize = kDefaultChunkSize);
~List();
inline const item_t &GetDefaultItem() const;
inline item_t &GetDefaultItem();
bool AddItem(const item_t &item, int32 index);
bool AddItem(const item_t &item);
// bool AddList(list_t *list, int32 index);
// bool AddList(list_t *list);
bool RemoveItem(const item_t &item);
bool RemoveItem(int32 index);
bool ReplaceItem(int32 index, const item_t &item);
bool MoveItem(int32 oldIndex, int32 newIndex);
void MakeEmpty();
int32 CountItems() const;
bool IsEmpty() const;
const item_t &ItemAt(int32 index) const;
item_t &ItemAt(int32 index);
const item_t *Items() const;
int32 IndexOf(const item_t &item) const;
bool HasItem(const item_t &item) const;
// debugging
int32 GetCapacity() const { return fCapacity; }
private:
inline static void _MoveItems(item_t* items, int32 offset, int32 count);
bool _Resize(size_t count);
private:
size_t fCapacity;
size_t fChunkSize;
int32 fItemCount;
item_t *fItems;
};
// sDefaultItem
template<typename ITEM, typename DEFAULT_ITEM_SUPPLIER>
List<ITEM, DEFAULT_ITEM_SUPPLIER>::item_t
List<ITEM, DEFAULT_ITEM_SUPPLIER>::sDefaultItem(
DEFAULT_ITEM_SUPPLIER::GetItem());
// constructor
template<typename ITEM, typename DEFAULT_ITEM_SUPPLIER>
List<ITEM, DEFAULT_ITEM_SUPPLIER>::List(size_t chunkSize)
: fCapacity(0),
fChunkSize(chunkSize),
fItemCount(0),
fItems(NULL)
{
if (fChunkSize == 0 || fChunkSize > kMaximalChunkSize)
fChunkSize = kDefaultChunkSize;
_Resize(0);
}
// destructor
template<typename ITEM, typename DEFAULT_ITEM_SUPPLIER>
List<ITEM, DEFAULT_ITEM_SUPPLIER>::~List()
{
MakeEmpty();
free(fItems);
}
// GetDefaultItem
template<typename ITEM, typename DEFAULT_ITEM_SUPPLIER>
inline
const List<ITEM, DEFAULT_ITEM_SUPPLIER>::item_t &
List<ITEM, DEFAULT_ITEM_SUPPLIER>::GetDefaultItem() const
{
return sDefaultItem;
}
// GetDefaultItem
template<typename ITEM, typename DEFAULT_ITEM_SUPPLIER>
inline
List<ITEM, DEFAULT_ITEM_SUPPLIER>::item_t &
List<ITEM, DEFAULT_ITEM_SUPPLIER>::GetDefaultItem()
{
return sDefaultItem;
}
// _MoveItems
template<typename ITEM, typename DEFAULT_ITEM_SUPPLIER>
inline
void
List<ITEM, DEFAULT_ITEM_SUPPLIER>::_MoveItems(item_t* items, int32 offset, int32 count)
{
if (count > 0 && offset != 0)
memmove(items + offset, items, count * sizeof(item_t));
}
// AddItem
template<typename ITEM, typename DEFAULT_ITEM_SUPPLIER>
bool
List<ITEM, DEFAULT_ITEM_SUPPLIER>::AddItem(const item_t &item, int32 index)
{
bool result = (index >= 0 && index <= fItemCount
&& _Resize(fItemCount + 1));
if (result) {
_MoveItems(fItems + index, 1, fItemCount - index - 1);
new(fItems + index) item_t(item);
}
return result;
}
// AddItem
template<typename ITEM, typename DEFAULT_ITEM_SUPPLIER>
bool
List<ITEM, DEFAULT_ITEM_SUPPLIER>::AddItem(const item_t &item)
{
bool result = true;
if ((int32)fCapacity > fItemCount) {
new(fItems + fItemCount) item_t(item);
fItemCount++;
} else {
if ((result = _Resize(fItemCount + 1)))
new(fItems + (fItemCount - 1)) item_t(item);
}
return result;
}
// These don't use the copy constructor!
/*
// AddList
template<typename ITEM, typename DEFAULT_ITEM_SUPPLIER>
bool
List<ITEM, DEFAULT_ITEM_SUPPLIER>::AddList(list_t *list, int32 index)
{
bool result = (list && index >= 0 && index <= fItemCount);
if (result && list->fItemCount > 0) {
int32 count = list->fItemCount;
result = _Resize(fItemCount + count);
if (result) {
_MoveItems(fItems + index, count, fItemCount - index - count);
memcpy(fItems + index, list->fItems,
list->fItemCount * sizeof(item_t));
}
}
return result;
}
// AddList
template<typename ITEM, typename DEFAULT_ITEM_SUPPLIER>
bool
List<ITEM, DEFAULT_ITEM_SUPPLIER>::AddList(list_t *list)
{
bool result = (list);
if (result && list->fItemCount > 0) {
int32 index = fItemCount;
int32 count = list->fItemCount;
result = _Resize(fItemCount + count);
if (result) {
memcpy(fItems + index, list->fItems,
list->fItemCount * sizeof(item_t));
}
}
return result;
}
*/
// RemoveItem
template<typename ITEM, typename DEFAULT_ITEM_SUPPLIER>
bool
List<ITEM, DEFAULT_ITEM_SUPPLIER>::RemoveItem(const item_t &item)
{
int32 index = IndexOf(item);
bool result = (index >= 0);
if (result)
RemoveItem(index);
return result;
}
// RemoveItem
template<typename ITEM, typename DEFAULT_ITEM_SUPPLIER>
bool
List<ITEM, DEFAULT_ITEM_SUPPLIER>::RemoveItem(int32 index)
{
if (index >= 0 && index < fItemCount) {
fItems[index].~item_t();
_MoveItems(fItems + index + 1, -1, fItemCount - index - 1);
_Resize(fItemCount - 1);
return true;
}
return false;
}
// ReplaceItem
template<typename ITEM, typename DEFAULT_ITEM_SUPPLIER>
bool
List<ITEM, DEFAULT_ITEM_SUPPLIER>::ReplaceItem(int32 index, const item_t &item)
{
if (index >= 0 && index < fItemCount) {
fItems[index] = item;
return true;
}
return false;
}
// MoveItem
template<typename ITEM, typename DEFAULT_ITEM_SUPPLIER>
bool
List<ITEM, DEFAULT_ITEM_SUPPLIER>::MoveItem(int32 oldIndex, int32 newIndex)
{
if (oldIndex >= 0 && oldIndex < fItemCount
&& newIndex >= 0 && newIndex <= fItemCount) {
if (oldIndex < newIndex - 1) {
item_t item = fItems[oldIndex];
_MoveItems(fItems + oldIndex + 1, -1, newIndex - oldIndex - 1);
fItems[newIndex] = item;
} else if (oldIndex > newIndex) {
item_t item = fItems[oldIndex];
_MoveItems(fItems + newIndex, 1, oldIndex - newIndex);
fItems[newIndex] = item;
}
return true;
}
return false;
}
// MakeEmpty
template<typename ITEM, typename DEFAULT_ITEM_SUPPLIER>
void
List<ITEM, DEFAULT_ITEM_SUPPLIER>::MakeEmpty()
{
for (int32 i = 0; i < fItemCount; i++)
fItems[i].~item_t();
_Resize(0);
}
// CountItems
template<typename ITEM, typename DEFAULT_ITEM_SUPPLIER>
int32
List<ITEM, DEFAULT_ITEM_SUPPLIER>::CountItems() const
{
return fItemCount;
}
// IsEmpty
template<typename ITEM, typename DEFAULT_ITEM_SUPPLIER>
bool
List<ITEM, DEFAULT_ITEM_SUPPLIER>::IsEmpty() const
{
return (fItemCount == 0);
}
// ItemAt
template<typename ITEM, typename DEFAULT_ITEM_SUPPLIER>
const List<ITEM, DEFAULT_ITEM_SUPPLIER>::item_t &
List<ITEM, DEFAULT_ITEM_SUPPLIER>::ItemAt(int32 index) const
{
if (index >= 0 && index < fItemCount)
return fItems[index];
return sDefaultItem;
}
// ItemAt
template<typename ITEM, typename DEFAULT_ITEM_SUPPLIER>
List<ITEM, DEFAULT_ITEM_SUPPLIER>::item_t &
List<ITEM, DEFAULT_ITEM_SUPPLIER>::ItemAt(int32 index)
{
if (index >= 0 && index < fItemCount)
return fItems[index];
return sDefaultItem;
}
// Items
template<typename ITEM, typename DEFAULT_ITEM_SUPPLIER>
const List<ITEM, DEFAULT_ITEM_SUPPLIER>::item_t *
List<ITEM, DEFAULT_ITEM_SUPPLIER>::Items() const
{
return fItems;
}
// IndexOf
template<typename ITEM, typename DEFAULT_ITEM_SUPPLIER>
int32
List<ITEM, DEFAULT_ITEM_SUPPLIER>::IndexOf(const item_t &item) const
{
for (int32 i = 0; i < fItemCount; i++) {
if (fItems[i] == item)
return i;
}
return -1;
}
// HasItem
template<typename ITEM, typename DEFAULT_ITEM_SUPPLIER>
bool
List<ITEM, DEFAULT_ITEM_SUPPLIER>::HasItem(const item_t &item) const
{
return (IndexOf(item) >= 0);
}
// _Resize
template<typename ITEM, typename DEFAULT_ITEM_SUPPLIER>
bool
List<ITEM, DEFAULT_ITEM_SUPPLIER>::_Resize(size_t count)
{
bool result = true;
// calculate the new capacity
int32 newSize = count;
if (newSize <= 0)
newSize = 1;
newSize = ((newSize - 1) / fChunkSize + 1) * fChunkSize;
// resize if necessary
if ((size_t)newSize != fCapacity) {
item_t* newItems
= (item_t*)realloc(fItems, newSize * sizeof(item_t));
if (newItems) {
fItems = newItems;
fCapacity = newSize;
} else
result = false;
}
if (result)
fItemCount = count;
return result;
}
#endif // LIST_H

View File

@ -24,7 +24,8 @@ main()
if (error != B_OK)
printf("creating the file device failed: %s\n", strerror(error));
if (manager->Lock()) {
for (int32 i = 0; KDiskDevice *device = manager->DeviceAt(i); i++) {
for (int32 cookie = 0;
KDiskDevice *device = manager->NextDevice(&cookie); ) {
device->Dump();
printf("\n");
}

View File

@ -3,6 +3,7 @@ SubDir OBOS_TOP src tests kernel core disk_device_manager ;
#UsePrivateHeaders $(DOT) ;
UsePrivateHeaders shared ;
UsePrivateHeaders [ FDirName kernel disk_device_manager ] ;
UsePrivateHeaders [ FDirName kernel util ] ;
UseHeaders [ FDirName $(OBOS_TOP) src kernel core disk_device_manager ] ;
SimpleTest DiskDeviceManagerTest