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 : DoublyLinkedListLinkImpl<FUSEEntry> { 39 FUSENode* parent; 40 char* name; 41 FUSENode* node; 42 FUSEEntry* hashLink; 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 { 81 ino_t id; 82 FUSEEntryList entries; 83 int type; 84 int32 refCount; 85 bool dirty; 86 FUSENode* hashLink; 87 88 FUSENode(ino_t id, int type) 89 : 90 id(id), 91 type(type), 92 refCount(1), 93 dirty(false) 94 { 95 } 96 97 FUSENode* Parent() const 98 { 99 FUSEEntry* entry = entries.Head(); 100 return entry != NULL ? entry->parent : NULL; 101 } 102 }; 103 104 105 struct FUSEEntryHashDefinition { 106 typedef FUSEEntryRef KeyType; 107 typedef FUSEEntry ValueType; 108 109 size_t HashKey(const FUSEEntryRef& key) const 110 { return ((uint32)key.parentID ^ (uint32)(key.parentID >> 32)) * 37 111 + string_hash(key.name); } 112 size_t Hash(const FUSEEntry* value) const 113 { return HashKey(FUSEEntryRef(value->parent->id, value->name)); } 114 bool Compare(const FUSEEntryRef& key, const FUSEEntry* value) const 115 { return value->parent->id == key.parentID 116 && strcmp(value->name, key.name) == 0; } 117 FUSEEntry*& GetLink(FUSEEntry* value) const 118 { return value->hashLink; } 119 }; 120 121 122 struct FUSENodeHashDefinition { 123 typedef ino_t KeyType; 124 typedef FUSENode ValueType; 125 126 size_t HashKey(ino_t key) const 127 { return (uint32)key ^ (uint32)(key >> 32); } 128 size_t Hash(const FUSENode* value) const 129 { return HashKey(value->id); } 130 bool Compare(ino_t key, const FUSENode* value) const 131 { return value->id == key; } 132 FUSENode*& GetLink(FUSENode* value) const 133 { return value->hashLink; } 134 }; 135 136 137 typedef BOpenHashTable<FUSEEntryHashDefinition> FUSEEntryTable; 138 typedef BOpenHashTable<FUSENodeHashDefinition> FUSENodeTable; 139 140 141 } // namespace UserlandFS 142 143 using UserlandFS::FUSENode; 144 145 146 #endif // USERLAND_FS_FUSE_ENTRY_H 147