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