1 /* 2 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 #ifndef USERLAND_FS_FUSE_ENTRY_H 6 #define USERLAND_FS_FUSE_ENTRY_H 7 8 #include <new> 9 10 #include <RWLockManager.h> 11 12 #include <util/DoublyLinkedList.h> 13 #include <util/OpenHashTable.h> 14 15 #include "String.h" 16 17 #include "fuse_api.h" 18 19 20 namespace UserlandFS { 21 22 struct FUSENode; 23 24 25 struct FUSEEntryRef { 26 ino_t parentID; 27 const char* name; 28 29 FUSEEntryRef(ino_t parentID, const char* name) 30 : 31 parentID(parentID), 32 name(name) 33 { 34 } 35 }; 36 37 38 struct FUSEEntry : public HashTableLink<FUSEEntry>, 39 DoublyLinkedListLinkImpl<FUSEEntry> { 40 FUSENode* parent; 41 char* name; 42 FUSENode* node; 43 44 FUSEEntry() 45 : 46 name(NULL) 47 { 48 } 49 50 ~FUSEEntry() 51 { 52 free(name); 53 } 54 55 56 static FUSEEntry* Create(FUSENode* parent, const char* name, FUSENode* node) 57 { 58 FUSEEntry* entry = new(std::nothrow) FUSEEntry; 59 if (entry == NULL) 60 return NULL; 61 62 char* clonedName = strdup(name); 63 if (clonedName == NULL) { 64 delete entry; 65 return NULL; 66 } 67 68 entry->parent = parent; 69 entry->name = clonedName; 70 entry->node = node; 71 72 return entry; 73 } 74 }; 75 76 77 typedef DoublyLinkedList<FUSEEntry> FUSEEntryList; 78 79 80 struct FUSENode : RWLockable, HashTableLink<FUSENode> { 81 ino_t id; 82 FUSEEntryList entries; 83 int type; 84 int32 refCount; 85 bool dirty; 86 87 FUSENode(ino_t id, int type) 88 : 89 id(id), 90 type(type), 91 refCount(1), 92 dirty(false) 93 { 94 } 95 96 FUSENode* Parent() const 97 { 98 FUSEEntry* entry = entries.Head(); 99 return entry != NULL ? entry->parent : NULL; 100 } 101 }; 102 103 104 struct FUSEEntryHashDefinition { 105 typedef FUSEEntryRef KeyType; 106 typedef FUSEEntry ValueType; 107 108 size_t HashKey(const FUSEEntryRef& key) const 109 { return ((uint32)key.parentID ^ (uint32)(key.parentID >> 32)) * 37 110 + string_hash(key.name); } 111 size_t Hash(const FUSEEntry* value) const 112 { return HashKey(FUSEEntryRef(value->parent->id, value->name)); } 113 bool Compare(const FUSEEntryRef& key, const FUSEEntry* value) const 114 { return value->parent->id == key.parentID 115 && strcmp(value->name, key.name) == 0; } 116 HashTableLink<FUSEEntry>* GetLink(FUSEEntry* value) const 117 { return value; } 118 }; 119 120 121 struct FUSENodeHashDefinition { 122 typedef ino_t KeyType; 123 typedef FUSENode ValueType; 124 125 size_t HashKey(ino_t key) const 126 { return (uint32)key ^ (uint32)(key >> 32); } 127 size_t Hash(const FUSENode* value) const 128 { return HashKey(value->id); } 129 bool Compare(ino_t key, const FUSENode* value) const 130 { return value->id == key; } 131 HashTableLink<FUSENode>* GetLink(FUSENode* value) const 132 { return value; } 133 }; 134 135 136 typedef OpenHashTable<FUSEEntryHashDefinition> FUSEEntryTable; 137 typedef OpenHashTable<FUSENodeHashDefinition> FUSENodeTable; 138 139 140 } // namespace UserlandFS 141 142 using UserlandFS::FUSENode; 143 144 145 #endif // USERLAND_FS_FUSE_ENTRY_H 146