1 karl 1.21 //%2006////////////////////////////////////////////////////////////////////////
|
2 mike 1.9 //
|
3 karl 1.19 // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
4 // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
5 // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
|
6 karl 1.18 // IBM Corp.; EMC Corporation, The Open Group.
|
7 karl 1.19 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
8 // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
|
9 karl 1.20 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
10 // EMC Corporation; VERITAS Software Corporation; The Open Group.
|
11 karl 1.21 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
12 // EMC Corporation; Symantec Corporation; The Open Group.
|
13 mike 1.9 //
14 // Permission is hereby granted, free of charge, to any person obtaining a copy
|
15 kumpf 1.14 // of this software and associated documentation files (the "Software"), to
16 // deal in the Software without restriction, including without limitation the
17 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
18 mike 1.9 // sell copies of the Software, and to permit persons to whom the Software is
19 // furnished to do so, subject to the following conditions:
|
20 karl 1.23 //
|
21 kumpf 1.14 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
|
22 mike 1.9 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
23 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
|
24 kumpf 1.14 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
25 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
26 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
27 mike 1.9 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30 //==============================================================================
31 //
32 //%/////////////////////////////////////////////////////////////////////////////
33
34 #ifndef Pegasus_InstanceIndexFile_h
35 #define Pegasus_InstanceIndexFile_h
36
|
37 kumpf 1.17 #include <fstream>
|
38 mike 1.9 #include <Pegasus/Common/Config.h>
39 #include <Pegasus/Common/String.h>
|
40 kumpf 1.16 #include <Pegasus/Common/InternalException.h>
|
41 kumpf 1.13 #include <Pegasus/Common/CIMObjectPath.h>
|
42 kumpf 1.15 #include <Pegasus/Repository/Linkage.h>
|
43 mike 1.9
44 PEGASUS_NAMESPACE_BEGIN
45
|
46 mike 1.11 /** This class manages access to an "instance index file" which maps
|
47 kumpf 1.22 instance names to offsets of the instances contained in the "instance
48 data file".
|
49 mike 1.11
|
50 kumpf 1.24 All files belonging to the instance repository are stored under the
51 repository/instances directory. For each class, two files are maintained:
52 an index file (with a ".idx" extension) and an instance file which bears
53 the name of the class whose instances it contains. For example, suppose
54 there is a class called "Zebra". Then two files are used to manage its
55 instances:
56
57 <pre>
58 repository/instances/Zebra.idx (called the index file)
59 repository/instances/Zebra (called the instance file)
60 </pre>
61
62 The first line of the index file is a free count, expressed as eight hex
|
63 kumpf 1.22 digits followed by a newline. The free count indicates how many instances
64 are free (but not reclaimed). When instances are deleted or modified, the
|
65 mike 1.11 corresponding entry in this index file is marked as free (by changing the
|
66 kumpf 1.24 first column of the entry from '0' to '1'). To improve performance,
67 reclamation of unused space in the instance file (called gaps) is
68 postponed until there are m gaps.
69
70 Reorganization is expensive: the entire instance file and index file must
71 be rewritten. The time complexity is O(n) where n is the number of
72 instances in the file. By postponing reorganization, the time complexity
73 may be reduced to O(1).
|
74 mike 1.11
75 All subsequent lines contain an entry with the following form:
|
76 kumpf 1.22
|
77 mike 1.9 <pre>
|
78 kumpf 1.24 <free> <hash-code> <offset> <size> ClassName.key1=val1,...,keyN=valN
|
79 mike 1.9 </pre>
80
|
81 kumpf 1.24 <ul>
82 <li>
83 free - '1' if the corresponding instance was deleted, '0' otherwise.
84 When instances are deleted, the corresponding entry in the index file
85 is marked as free and a gap is left in the instance file until
86 reorganization time.
87 </li>
88 <li>
89 hash-code - hash code for the key field below. This field is provided to
90 speed lookup of index entries. When looking up an entry, compute the
91 hash code of the key and look for entries with the same hash code.
92 It is still necessary to compare the keys when the hash codes are
93 the same (since collisions are possible), but only when they are the
94 same which is rare and hence this scheme saves many comparisons.
95 </li>
96 <li>
97 offset - offset within the instance file to where the instance begins.
98 </li>
99 <li>
100 size - size in bytes of the instance itself (as it appears in the instance
101 file).
102 kumpf 1.24 </li>
103 <li>
104 key - the compound key of the instance (including all key binding pairs).
105 </li>
106 </ul>
|
107 mike 1.10
|
108 mike 1.11 Here's an example of an index file:
|
109 mike 1.9
110 <pre>
|
111 kumpf 1.22 00000001
112 0 A6B275A9 0 1425 Employee.ssn=444332222
113 1 A6BA08B1 1425 1430 Employee.ssn=555667777
|
114 mike 1.9 </pre>
115
|
116 kumpf 1.24 Notice that the dirty count is equal to one and that one entry is marked
117 as deleted (these quantities must be equal). This indicates that the
118 instance file has one instance which is no longer used. The space used by
119 this instance will be reclaimed during reorganization.
120
121 The layout of the instance file is trivial. Instances are always appended
122 to the instance file. The instances are kept end-to-end in the file.
123
|
124 mike 1.11 To lookup an entry in the index file, first take the hash code of the
125 target key. Then find the first non-free entry whose hash code and key
126 are the same as the target hash code and key. Note that an entry may
127 usually be ruled out by comparing the hash codes (except in the case of
128 clashes).
|
129 kumpf 1.22
|
130 kumpf 1.24 There are three operations which may be performed on the instance
131 repository: create, modify, and delete.
132
133 Creation. During creation, the instance is appended to the instance file
134 and an entry is appended to the index file. If an instance with the same
135 key is found, then the operation is disallowed.
136
137 Deletion. To delete an instance, the corresponding entry in the index file
138 is marked as deleted (by changing the first column from '0' to '1'). And
139 then the dirty count is incremented and updated. If the dirty count has
140 reached the configured threshold, the index and instance files are
141 reogranized.
142
143 Modification. To modify an instance, the new modified instance is appended
144 to the instance file. Next the old entry with the same key is marked as
145 deleted. Finally, a new entry is inserted into the index file.
|
146 mike 1.9 */
147 class PEGASUS_REPOSITORY_LINKAGE InstanceIndexFile
148 {
149 public:
|
150 kumpf 1.22
151 /** Searches the instance index file for the given instance name. Sets
|
152 mike 1.10 the index parameter to the corresponding index, and sets the size
153 parameter to the corresponding instance record size. Returns true
154 on success.
155
|
156 mike 1.11 @param path the file path of the instance index file
157 @param instanceName the name of the instance
158 @param indexOut the index of the instance record found
159 @param sizeOut the size of the instance record found
160 @return true if the instance is found; false otherwise.
|
161 mike 1.9 */
|
162 mike 1.11 static Boolean lookupEntry(
|
163 kumpf 1.22 const String& path,
164 const CIMObjectPath& instanceName,
165 Uint32& indexOut,
166 Uint32& sizeOut);
|
167 mike 1.9
|
168 mike 1.11 /** Creates a new entry in the instance index file. Saves the index and
|
169 mike 1.10 size of the instance record passed in. This method assumes that the
|
170 kumpf 1.22 keys in the instance name are in sorted order. This must be done
|
171 mike 1.10 prior to calling the method. Returns true on success.
172
|
173 mike 1.11 @param path the file path of the instance index file
174 @param instanceName the name of the instance
175 @param indexIn the index of the new instance record
|
176 kumpf 1.22 @param sizeIn the size of the new instance record
|
177 mike 1.11 @return true if successful; false otherwise.
|
178 mike 1.9 */
|
179 mike 1.11 static Boolean createEntry(
|
180 kumpf 1.22 const String& path,
181 const CIMObjectPath& instanceName,
182 Uint32 indexIn,
|
183 mike 1.11 Uint32 sizeIn);
|
184 mike 1.10
|
185 mike 1.11 /** Deletes the entry with the given instance name.
186 @param path path of the instance index file
187 @param instanceName name of the instance
188 @return true on success
|
189 mike 1.9 */
|
190 mike 1.11 static Boolean deleteEntry(
|
191 kumpf 1.22 const String& path,
192 const CIMObjectPath& instanceName,
193 Uint32& freeCount);
|
194 mike 1.9
|
195 mike 1.10 /** Modifies an entry by first removing the old entry and then inserting
|
196 mike 1.11 a new entry at the end of the file.
|
197 mike 1.10
|
198 mike 1.11 @param path the file path of the instance index file.
199 @param instanceName the name of the instance.
200 @param indexIn the index of the modified instance record.
201 @param sizeIn the size of the modified instance record.
202 @return true on success.
|
203 mike 1.10 */
|
204 mike 1.11 static Boolean modifyEntry(
|
205 kumpf 1.22 const String& path,
206 const CIMObjectPath& instanceName,
207 Uint32 indexIn,
|
208 mike 1.10 Uint32 sizeIn,
|
209 kumpf 1.22 Uint32& freeCount);
|
210 mike 1.10
211 /** Gets the information stored in the index file for all the instances
|
212 kumpf 1.22 of the given class. Appends the instance names, indices and sizes
|
213 mike 1.10 to the given arrays (does not clear the arrays first). Returns
214 true on success.
215
|
216 mike 1.11 @param path path of the instance index file.
217 @param instanceNames array to hold the instance names.
218 @param indices array to hold the indices of the instance records.
219 @param sizes an array to hold the sizes of the instance records.
220 @return true on success.
|
221 mike 1.9 */
|
222 mike 1.11 static Boolean enumerateEntries(
|
223 kumpf 1.22 const String& path,
224 Array<Uint32>& freeFlags,
225 Array<Uint32>& indices,
|
226 mike 1.11 Array<Uint32>& sizes,
|
227 kumpf 1.22 Array<CIMObjectPath>& instanceNames,
228 Boolean includeFreeEntries);
|
229 mike 1.11
|
230 kumpf 1.12
|
231 mike 1.11 /** Returns true if this index file has any non-free entries:
232 */
233 static Boolean hasNonFreeEntries(const String& path);
234
235 /** Begin a transaction to modify this file. The effect of subsequent
|
236 kumpf 1.22 modifications can be rolled back by calling rollbackTransaction().
237 The current implementation simply copies the index file to a a file
238 with the same name but with ".rollback" appended to it.
|
239 mike 1.11 */
240 static Boolean beginTransaction(const String& path);
241
|
242 kumpf 1.22 /** Roll back any changes to the file since the last time
|
243 mike 1.11 beginTransaction() was called. The current implementation deletes
|
244 kumpf 1.22 the current file and renames the rollback file to the same name.
|
245 mike 1.11 */
246 static Boolean rollbackTransaction(const String& path);
247
248 /** Commit changes made after beginTransaction() was called. The curent
|
249 kumpf 1.22 implementation simply removes the .rollback file.
|
250 mike 1.11 */
251 static Boolean commitTransaction(const String& path);
252
253 /** Compact the file by removing entries which are marked as free.
254 */
255 static Boolean compact(
256 const String& path);
|
257 mike 1.10
258 private:
|
259 mike 1.11
260 /** Open the index file and position the file pointer on the first
|
261 kumpf 1.22 entry (immediately after the free count). Create the file if it
262 does not exist and if the create flag is true (writing a free
|
263 kumpf 1.12 count of zero).
|
264 mike 1.11 */
265 static Boolean _openFile(
|
266 kumpf 1.22 const String& path,
|
267 kumpf 1.12 PEGASUS_STD(fstream)& fs,
268 Boolean create = false);
|
269 kumpf 1.22
|
270 mike 1.11 /** Appends a new entry to the index file; called by both createEntry()
271 and modifyEntry().
|
272 mike 1.10 */
|
273 mike 1.11 static Boolean _appendEntry(
274 PEGASUS_STD(fstream)& fs,
|
275 kumpf 1.13 const CIMObjectPath& instanceName,
|
276 mike 1.11 Uint32 indexIn,
277 Uint32 sizeIn);
|
278 kumpf 1.22
|
279 mike 1.11 /** Increment the index file's free count; called by _markEntryFree().
|
280 kumpf 1.22 The resulting value is left in the freeCount parameter.
|
281 mike 1.11 */
282 static Boolean _incrementFreeCount(
|
283 kumpf 1.22 PEGASUS_STD(fstream)& fs,
284 Uint32& freeCount);
|
285 mike 1.10
|
286 mike 1.11 /** Marks the entry matching the given instanceName as free; called by both
|
287 kumpf 1.22 deleteEntry() and modifyEntry().
|
288 mike 1.11 */
289 static Boolean _markEntryFree(
290 PEGASUS_STD(fstream)& fs,
|
291 kumpf 1.13 const CIMObjectPath& instanceName);
|
292 mike 1.11
293 /** Helper method for lookupEntry() which takes a file stream rather than
|
294 kumpf 1.22 a path.
|
295 mike 1.11 */
296 static Boolean _lookupEntry(
|
297 kumpf 1.22 PEGASUS_STD(fstream)& fs,
298 const CIMObjectPath& instanceName,
299 Uint32& indexOut,
300 Uint32& sizeOut,
301 Uint32& entryOffset);
|
302 mike 1.9 };
303
304 PEGASUS_NAMESPACE_END
305
306 #endif /* Pegasus_InstanceIndexFile_h */
|