1// NodeChildTable.h 2 3#ifndef NODE_CHILD_TABLE_H 4#define NODE_CHILD_TABLE_H 5 6#include "AllocationInfo.h" 7#include "Debug.h" 8#include "Misc.h" 9#include "Node.h" 10#include "OpenHashTable.h" 11 12// NodeChildHashElement 13template<typename ParentNode, typename NodeChild> 14class NodeChildHashElement : public OpenHashElement { 15private: 16 typedef NodeChildHashElement<ParentNode, NodeChild> Element; 17public: 18 19 NodeChildHashElement() : OpenHashElement(), fID(-1), fChild(NULL) 20 { 21 fNext = -1; 22 } 23 24 static inline uint32 HashFor(vnode_id id, const char *name) 25 { 26 return node_child_hash(id, name); 27 } 28 29 static inline uint32 HashFor(ParentNode *parent, NodeChild *child) 30 { 31 return node_child_hash(parent->GetID(), child->GetName()); 32 } 33 34 inline uint32 Hash() const 35 { 36 return HashFor(fID, fChild->GetName()); 37 } 38 39 inline bool Equals(vnode_id id, const char *name) 40 { 41 return (fID == id && !strcmp(fChild->GetName(), name)); 42 } 43 44 inline bool operator==(const OpenHashElement &_element) const 45 { 46 const Element &element = static_cast<const Element&>(_element); 47 return Equals(element.fID, element.fChild->GetName()); 48 } 49 50 inline void Adopt(Element &element) 51 { 52 fID = element.fID; 53 fChild = element.fChild; 54 } 55 56 vnode_id fID; 57 NodeChild *fChild; 58}; 59 60// NodeChildTable 61template<typename ParentNode, typename NodeChild> 62class NodeChildTable { 63public: 64 NodeChildTable(); 65 ~NodeChildTable(); 66 67 status_t InitCheck() const; 68 69 status_t AddNodeChild(ParentNode *node, NodeChild *child); 70 status_t AddNodeChild(vnode_id, NodeChild *child); 71 status_t RemoveNodeChild(ParentNode *node, NodeChild *child); 72 status_t RemoveNodeChild(vnode_id id, NodeChild *child); 73 status_t RemoveNodeChild(vnode_id id, const char *name); 74 NodeChild *GetNodeChild(vnode_id id, const char *name); 75 76protected: 77 typedef NodeChildHashElement<ParentNode, NodeChild> Element; 78 79private: 80 Element *_FindElement(vnode_id id, const char *name) const; 81 82protected: 83 OpenHashElementArray<Element> fElementArray; 84 OpenHashTable<Element, OpenHashElementArray<Element> > fTable; 85}; 86 87// define convenient instantiation types 88 89// DirectoryEntryTable 90class DirectoryEntryTable : public NodeChildTable<Directory, Entry> { 91public: 92 DirectoryEntryTable() {} 93 ~DirectoryEntryTable() {} 94 95 void GetAllocationInfo(AllocationInfo &info) 96 { 97 info.AddDirectoryEntryTableAllocation(fTable.ArraySize(), 98 fTable.VectorSize(), 99 sizeof(Element), 100 fTable.CountElements()); 101 } 102}; 103 104// NodeAttributeTable 105class NodeAttributeTable : public NodeChildTable<Node, Attribute> { 106public: 107 NodeAttributeTable() {} 108 ~NodeAttributeTable() {} 109 110 void GetAllocationInfo(AllocationInfo &info) 111 { 112 info.AddNodeAttributeTableAllocation(fTable.ArraySize(), 113 fTable.VectorSize(), 114 sizeof(Element), 115 fTable.CountElements()); 116 } 117}; 118 119 120// NodeChildTable implementation 121 122// constructor 123template<typename ParentNode, typename NodeChild> 124NodeChildTable<ParentNode, NodeChild>::NodeChildTable() 125 : fElementArray(1000), 126 fTable(1000, &fElementArray) 127{ 128} 129 130// destructor 131template<typename ParentNode, typename NodeChild> 132NodeChildTable<ParentNode, NodeChild>::~NodeChildTable() 133{ 134} 135 136// InitCheck 137template<typename ParentNode, typename NodeChild> 138status_t 139NodeChildTable<ParentNode, NodeChild>::InitCheck() const 140{ 141 RETURN_ERROR(fTable.InitCheck() && fElementArray.InitCheck() 142 ? B_OK : B_NO_MEMORY); 143} 144 145// AddNodeChild 146template<typename ParentNode, typename NodeChild> 147status_t 148NodeChildTable<ParentNode, NodeChild>::AddNodeChild(ParentNode *node, 149 NodeChild *child) 150{ 151 status_t error = (node && child ? B_OK : B_BAD_VALUE); 152 if (error == B_OK) 153 error = AddNodeChild(node->GetID(), child); 154 return error; 155} 156 157// AddNodeChild 158template<typename ParentNode, typename NodeChild> 159status_t 160NodeChildTable<ParentNode, NodeChild>::AddNodeChild(vnode_id id, 161 NodeChild *child) 162{ 163 status_t error = (child ? B_OK : B_BAD_VALUE); 164 if (error == B_OK) { 165 Element *element = fTable.Add(Element::HashFor(id, child->GetName())); 166 if (element) { 167 element->fID = id; 168 element->fChild = child; 169 } else 170 SET_ERROR(error, B_NO_MEMORY); 171 } 172 return error; 173} 174 175// RemoveNodeChild 176template<typename ParentNode, typename NodeChild> 177status_t 178NodeChildTable<ParentNode, NodeChild>::RemoveNodeChild(ParentNode *node, 179 NodeChild *child) 180{ 181 status_t error = (node && child ? B_OK : B_BAD_VALUE); 182 if (error == B_OK) 183 error = RemoveNodeChild(node->GetID(), child->GetName()); 184 return error; 185} 186 187// RemoveNodeChild 188template<typename ParentNode, typename NodeChild> 189status_t 190NodeChildTable<ParentNode, NodeChild>::RemoveNodeChild(vnode_id id, 191 NodeChild *child) 192{ 193 status_t error = (child ? B_OK : B_BAD_VALUE); 194 if (error == B_OK) 195 error = RemoveNodeChild(id, child->GetName()); 196 return error; 197} 198 199// RemoveNodeChild 200template<typename ParentNode, typename NodeChild> 201status_t 202NodeChildTable<ParentNode, NodeChild>::RemoveNodeChild(vnode_id id, 203 const char *name) 204{ 205 status_t error = B_OK; 206 if (Element *element = _FindElement(id, name)) 207 fTable.Remove(element); 208 else 209 error = B_ERROR; 210 return error; 211} 212 213// GetNodeChild 214template<typename ParentNode, typename NodeChild> 215NodeChild * 216NodeChildTable<ParentNode, NodeChild>::GetNodeChild(vnode_id id, 217 const char *name) 218{ 219 NodeChild *child = NULL; 220 if (Element *element = _FindElement(id, name)) 221 child = element->fChild; 222 return child; 223} 224 225// _FindElement 226template<typename ParentNode, typename NodeChild> 227typename NodeChildTable<ParentNode, NodeChild>::Element * 228NodeChildTable<ParentNode, NodeChild>::_FindElement(vnode_id id, 229 const char *name) const 230{ 231 Element *element = fTable.FindFirst(Element::HashFor(id, name)); 232 while (element && !element->Equals(id, name)) { 233 if (element->fNext >= 0) 234 element = fTable.ElementAt(element->fNext); 235 else 236 element = NULL; 237 } 238 return element; 239} 240 241 242// undefine the PRINT from <Debug.h> 243//#undef PRINT 244 245#endif // NODE_CHILD_TABLE_H 246