xref: /haiku/src/add-ons/kernel/file_systems/ramfs/IndexDirectory.cpp (revision 9e54316c528c34ee76f4d0d21150ceadd031c4de)
1 /*
2  * Copyright 2007, Ingo Weinhold, ingo_weinhold@gmx.de.
3  * All rights reserved. Distributed under the terms of the MIT license.
4  */
5 
6 #include <TypeConstants.h>
7 
8 #include "AttributeIndexImpl.h"
9 #include "DebugSupport.h"
10 #include "IndexDirectory.h"
11 #include "LastModifiedIndex.h"
12 #include "NameIndex.h"
13 #include "SizeIndex.h"
14 
15 // constructor
16 IndexDirectory::IndexDirectory(Volume *volume)
17 	: fVolume(volume),
18 	  fNameIndex(NULL),
19 	  fLastModifiedIndex(NULL),
20 	  fSizeIndex(NULL),
21 	  fIndices()
22 {
23 	fNameIndex = new(nothrow) NameIndex(volume);
24 	fLastModifiedIndex = new(nothrow) LastModifiedIndex(volume);
25 	fSizeIndex = new(nothrow) SizeIndex(volume);
26 	if (fNameIndex && fLastModifiedIndex && fSizeIndex) {
27 		if (!fIndices.AddItem(fNameIndex)
28 			|| !fIndices.AddItem(fLastModifiedIndex)
29 			|| !fIndices.AddItem(fSizeIndex)) {
30 			fIndices.MakeEmpty();
31 			delete fNameIndex;
32 			delete fLastModifiedIndex;
33 			delete fSizeIndex;
34 			fNameIndex = NULL;
35 			fLastModifiedIndex = NULL;
36 			fSizeIndex = NULL;
37 		}
38 	}
39 }
40 
41 // destructor
42 IndexDirectory::~IndexDirectory()
43 {
44 	// delete the default indices
45 	if (fNameIndex) {
46 		fIndices.RemoveItem(fNameIndex);
47 		delete fNameIndex;
48 	}
49 	if (fLastModifiedIndex) {
50 		fIndices.RemoveItem(fLastModifiedIndex);
51 		delete fLastModifiedIndex;
52 	}
53 	if (fSizeIndex) {
54 		fIndices.RemoveItem(fSizeIndex);
55 		delete fSizeIndex;
56 	}
57 	// delete the attribute indices
58 	int32 count = fIndices.CountItems();
59 	for (int i = 0; i < count; i++)
60 		delete fIndices.ItemAt(i);
61 }
62 
63 // InitCheck
64 status_t
65 IndexDirectory::InitCheck() const
66 {
67 	return (fNameIndex && fLastModifiedIndex && fSizeIndex ? B_OK
68 														   : B_NO_MEMORY);
69 }
70 
71 // CreateIndex
72 status_t
73 IndexDirectory::CreateIndex(const char *name, uint32 type,
74 							AttributeIndex **_index)
75 {
76 	status_t error = (name ? B_OK : B_BAD_VALUE);
77 	if (error == B_OK) {
78 		if (!FindIndex(name)) {
79 			// create the index
80 			AttributeIndex *index = NULL;
81 			switch (type) {
82 				case B_INT32_TYPE:
83 					index = new(nothrow) AttributeIndexImpl(fVolume,
84 						name, type, sizeof(int32));
85 					break;
86 				case B_UINT32_TYPE:
87 					index = new(nothrow) AttributeIndexImpl(fVolume,
88 						name, type, sizeof(uint32));
89 					break;
90 				case B_INT64_TYPE:
91 					index = new(nothrow) AttributeIndexImpl(fVolume,
92 						name, type, sizeof(int64));
93 					break;
94 				case B_UINT64_TYPE:
95 					index = new(nothrow) AttributeIndexImpl(fVolume,
96 						name, type, sizeof(uint64));
97 					break;
98 				case B_FLOAT_TYPE:
99 					index = new(nothrow) AttributeIndexImpl(fVolume,
100 						name, type, sizeof(float));
101 					break;
102 				case B_DOUBLE_TYPE:
103 					index = new(nothrow) AttributeIndexImpl(fVolume,
104 						name, type, sizeof(double));
105 					break;
106 				case B_STRING_TYPE:
107 					index = new(nothrow) AttributeIndexImpl(fVolume,
108 						name, type, 0);
109 					break;
110 				default:
111 					error = B_BAD_VALUE;
112 					break;
113 			}
114 			if (error == B_OK && !index)
115 				error = B_NO_MEMORY;
116 			// add the index
117 			if (error == B_OK) {
118 				if (fIndices.AddItem(index)) {
119 					if (_index)
120 						*_index = index;
121 				} else {
122 					delete index;
123 					error = B_NO_MEMORY;
124 				}
125 			}
126 		} else
127 			error = B_FILE_EXISTS;
128 	}
129 	return error;
130 }
131 
132 // DeleteIndex
133 bool
134 IndexDirectory::DeleteIndex(const char *name, uint32 type)
135 {
136 	return DeleteIndex(FindIndex(name, type));
137 }
138 
139 // DeleteIndex
140 bool
141 IndexDirectory::DeleteIndex(Index *index)
142 {
143 	bool result = false;
144 	if (index && !IsSpecialIndex(index)) {
145 		int32 i = fIndices.IndexOf(index);
146 		if (i >= 0) {
147 			fIndices.RemoveItem(i);
148 			delete index;
149 			result = true;
150 		}
151 	}
152 	return result;
153 }
154 
155 // FindIndex
156 Index *
157 IndexDirectory::FindIndex(const char *name)
158 {
159 	if (name) {
160 		int32 count = fIndices.CountItems();
161 		for (int32 i = 0; i < count; i++) {
162 			Index *index = fIndices.ItemAt(i);
163 			if (!strcmp(index->GetName(), name))
164 				return index;
165 		}
166 	}
167 	return NULL;
168 }
169 
170 // FindIndex
171 Index *
172 IndexDirectory::FindIndex(const char *name, uint32 type)
173 {
174 	Index *index = FindIndex(name);
175 	if (index && index->GetType() != type)
176 		index = NULL;
177 	return index;
178 }
179 
180 // FindAttributeIndex
181 AttributeIndex *
182 IndexDirectory::FindAttributeIndex(const char *name)
183 {
184 	AttributeIndex *attrIndex = NULL;
185 	if (Index *index = FindIndex(name))
186 		attrIndex = dynamic_cast<AttributeIndex*>(index);
187 	return attrIndex;
188 }
189 
190 // FindAttributeIndex
191 AttributeIndex *
192 IndexDirectory::FindAttributeIndex(const char *name, uint32 type)
193 {
194 	AttributeIndex *attrIndex = NULL;
195 	if (Index *index = FindIndex(name, type))
196 		attrIndex = dynamic_cast<AttributeIndex*>(index);
197 	return attrIndex;
198 }
199 
200 // IsSpecialIndex
201 bool
202 IndexDirectory::IsSpecialIndex(Index *index) const
203 {
204 	return (index == fNameIndex || index == fLastModifiedIndex
205 			|| index == fSizeIndex);
206 }
207 
208