Source code: org/apache/derby/iapi/store/raw/ContainerHandle.java
1 /*
2
3 Derby - Class org.apache.derby.iapi.store.raw.ContainerHandle
4
5 Copyright 1997, 2004 The Apache Software Foundation or its licensors, as applicable.
6
7 Licensed under the Apache License, Version 2.0 (the "License");
8 you may not use this file except in compliance with the License.
9 You may obtain a copy of the License at
10
11 http://www.apache.org/licenses/LICENSE-2.0
12
13 Unless required by applicable law or agreed to in writing, software
14 distributed under the License is distributed on an "AS IS" BASIS,
15 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 See the License for the specific language governing permissions and
17 limitations under the License.
18
19 */
20
21 package org.apache.derby.iapi.store.raw;
22
23 import org.apache.derby.iapi.store.access.SpaceInfo;
24 import org.apache.derby.iapi.error.StandardException;
25
26 import java.util.Properties;
27
28 /**
29 A Container contains a contigious address space of pages, the pages
30 start at page number Container.FIRST_PAGE_NUMBER and are numbered sequentially.
31
32 The page size is set at addContainer() time.
33
34
35 RESOLVE: this style of coding is not currently enforced
36 If the caller calls getPage (or one of its variants) more than once on the
37 same page, the caller must call unlatch a corresponding number of times in
38 order to ensure that the page is latched. For example:
39 <p>
40 <blockquote><pre>
41 Container c;
42 Page p1 = c.getPage(Container.FIRST_PAGE_NUMBER);
43 Page p2 = c.getPage(Container.FIRST_PAGE_NUMBER);
44 p1.unlatch(); -- Page is still latched.
45 p2.unlatch(); -- Page is now unlatched.
46 </pre></blockquote>
47
48 <p>
49 There is no restriction on the order in which latching and unlatching is
50 done. In the example, p1 could have been unlatched after p2 with no ill
51 effects.
52
53 <P> <B>Open container modes</B>
54 ContainerHandle.MODE are used to open or create the container.
55 Unlike TableProperties, MODEs are not permanantely associated with the
56 container, it is effective only for the lifetime of the containerHandle
57 itself.
58 <BR>A container may use any of these mode flags when it is opened.
59 <UL>
60 <LI>MODE_READONLY - Open the container in read only mode.
61 <LI>MODE_FORUPDATE - Open the container in update mode, if the underlying
62 storage does not allow updates
63 then the container will be opned in read only mode.
64 <LI>MODE_UNLOGGED - If Unset, any changes to the container are logged.
65 If set, any user changes to the container are unlogged. It is guaranteed
66 at commit time that all changes made during the transaction will have been
67 flushed to disk. Using this mode automatically opens the container in
68 container locking, isolation 3 level. The state of the container following
69 an abort or any type of rollback is unspecified.
70 <LI>MODE_CREATE_UNLOGGED - If set, not only are user changes to the
71 container are unlogged, page allocations are also unlogged. This MODE is
72 only useful for container is created in the same statement and no change on
73 the container (other than the create) is ever logged. The difference
74 between MODE_UNLOGGED and MODE_CREATE_UNLOGGED is that page allocation is
75 also unlogged and commit of nested transaction will not cause the container
76 to be forced from the cache. Unlike MODE_UNLOGGED, MODE_CREATE_UNLOGGED
77 does not force the cache. It is up to the client of raw store to force the
78 cache at the appropriate time - this allows a statement to create and open
79 the container serveral times for bulk loading without logging or doing any
80 synchronous I/O.
81 <LI>MODE_LOCK_NOWAIT - if set, then don't wait for the container lock, else
82 wait for the container lock. This flag only dictates whether the lock
83 should be waited for or not. After the container is successfully opened,
84 whether this bit is set or not has no effect on the container handle.
85 </UL>
86 If neither or both of the {MODE_READONLY, MODE_FORUPDATE} modes are
87 specified then the behaviour of the container is unspecified.
88 <BR>
89 MODE_UNLOGGED must be set for MODE_CREATE_UNLOGGED to be set.
90 <P>
91 <B>Temporary Containers</B><BR>
92 If when creating a container the segment used is
93 ContainerHandle.TEMPORARY_SEGMENT then the container is a temporary
94 container. Temporary containers are not logged or locked and do not live
95 across re-boots of the system. In addition any abort or rollback including
96 rollbacks to savepoints truncate the container if it has been opened for
97 update since the last commit or abort. Temporary containers are private
98 to a transaction and must only be used a single thread within the
99 transaction at any time, these restrictions are not currently enforced.
100 <BR>
101 When opening a temporary container for update access these additional mode
102 flags may be used
103 <UL>
104 <LI> MODE_TRUNCATE_ON_COMMIT - At commit/abort time container is truncated.
105 <LI> MODE_DROP_ON_COMMIT - At commit/abort time the container is dropped.
106 <LI> MODE_TEMP_IS_KEPT - At commit/abort time the container is kept around.
107 </UL>
108 If a temporary container is opened multiple times in the same transaction
109 with different modes then the most severe mode is used, ie. none <
110 truncate on commit < drop on commit.
111 The MODE_UNLOGGED, MODE_CREAT_UNLOGGED flags are ignored when opening a
112 temporary container, not logged is always assumed. */
113
114 public interface ContainerHandle
115 {
116
117 /**
118 Used in add container.
119 */
120 public static final int DEFAULT_PAGESIZE = -1;
121
122 public static final int DEFAULT_SPARESPACE = -1;
123
124 public static final int DEFAULT_ASSIGN_ID = 0;
125
126 /**
127 See comments above for these modes.
128 */
129 public static final int MODE_DEFAULT = 0x00000000;
130 public static final int MODE_UNLOGGED = 0x00000001;
131 public static final int MODE_CREATE_UNLOGGED = 0x00000002;
132 public static final int MODE_FORUPDATE = 0x00000004;
133 public static final int MODE_READONLY = 0x00000008;
134 public static final int MODE_TRUNCATE_ON_COMMIT = 0x00000010;
135 public static final int MODE_DROP_ON_COMMIT = 0x00000020;
136 public static final int MODE_OPEN_FOR_LOCK_ONLY = 0x00000040;
137 public static final int MODE_LOCK_NOWAIT = 0x00000080;
138 public static final int MODE_TRUNCATE_ON_ROLLBACK = 0x00000100; // internal raw store
139 public static final int MODE_FLUSH_ON_COMMIT = 0x00000200; // internal raw store
140 public static final int MODE_NO_ACTIONS_ON_COMMIT = 0x00000400; // internal raw store
141 public static final int MODE_TEMP_IS_KEPT = 0x00000800; // internal raw store
142
143 public static final int MODE_USE_UPDATE_LOCKS = 0x00001000; // external access
144 public static final int MODE_SECONDARY_LOCKED = 0x00002000; // external access
145 public static final int MODE_BASEROW_INSERT_LOCKED = 0x00004000; // external access
146
147 public static final int TEMPORARY_SEGMENT = -1;
148
149
150 /**
151 The first valid page number
152 */
153 public static final long FIRST_PAGE_NUMBER = 1;
154
155 /**
156 A page number that is guaranteed to be invalid.
157 */
158 public static final long INVALID_PAGE_NUMBER = -1;
159
160 /**
161 Return my identifier.
162 */
163 public ContainerKey getId();
164
165 /**
166 Return my unique identifier, this identifier will be unique to each
167 instance of an open container handle. This id is used by the locking
168 system to group locks to an open container handle.
169 */
170 public Object getUniqueId();
171
172 /**
173 * Is the container opened for read only or update?
174 *
175 * @return true if container is opened for read only, else false.
176 **/
177 boolean isReadOnly();
178
179 /**
180 Add an empty page to the container and obtain exclusive access to it.
181 <P>
182 Note that the added page may not be the last page in the Container.
183
184 Once the Page is no longer required the Page's unlatch() method must
185 be called.
186
187 @return a reference to the page that was added.
188
189 @see Page#unlatch
190
191 @exception StandardException Standard Cloudscape error policy
192 @exception StandardException If a page could not be allocated.
193 */
194 public Page addPage() throws StandardException;
195
196
197 /**
198 Release free space to the OS.
199 <P>
200 As is possible release any free space to the operating system. This
201 will usually mean releasing any free pages located at the end of the
202 file using the java truncate() interface.
203
204 @exception StandardException Standard Cloudscape error policy
205 */
206 public void compressContainer() throws StandardException;
207
208
209 /**
210 Add an empty page to the container and obtain exclusive access to it.
211 <P>
212 If flag == ADD_PAGE_DEFAULT, this call is identical to addPage().
213 <BR>
214 If flag == ADD_PAGE_BULK, then this call signifies to the container that
215 this addPage is part of a large number of additional pages and it is
216 desirable to do whatever possible to facilitate adding many subsequent pages.
217 The actual container implementation will decide whether or not to heed
218 this hint and what to do about it.
219
220 @return a reference to the page that was added.
221
222 @see Page#unlatch
223
224 @exception StandardException Standard Cloudscape error policy
225 @exception StandardException If a page could not be allocated.
226
227 */
228 public Page addPage(int flag) throws StandardException;
229 public static final int ADD_PAGE_DEFAULT = 0x1;
230 public static final int ADD_PAGE_BULK = 0x2;
231
232
233 /**
234 Try to preallocate numPage new pages if possible.
235 */
236 public void preAllocate(int numPage);
237
238
239 /**
240 Remove this page from the container and unlatch the page. <B>Caller
241 should commit or abort this transaction ASAP because failure to do so
242 will slow down page allocation of this container. </B>
243
244 <BR>The page to be removed must be latched and gotten (or added) by
245 this ContainerHandle. The page should not be used again after this
246 call as if it has been unlatched. If the call to removePage is
247 successful, this page is invalid should not be gotten again with
248 getPage.
249
250 <BR>RemovePage will guarantee to unlatch the page even if a
251 StandardException is thrown.
252
253 <P>
254 <B>Locking Policy</B>
255 <BR>
256 The page will not be freed until the transaction that removed the page
257 commits. A special RecordHandle.DEALLOC_PROTECTION_HANDLE lock will be
258 gotten for the transaction and which is used to prevent the page from
259 being freed. This lock will be held regardless of the default locking
260 policy of the transaction that called removedPage.
261
262 @see LockingPolicy
263 @see RecordHandle
264
265 @exception StandardException Standard Cloudscape error policy
266 */
267 public void removePage(Page page) throws StandardException;
268
269
270 /**
271 Obtain exclusive access to the page with the given page number.
272
273 Once the Page is no longer required the Page's unlatch() method must
274 be called.
275
276 <P>
277 The Page object is guaranteed to remain in-memory and exclusive to the
278 caller until its unlatch() method is called.
279
280 @return the required Page or null if the page does not exist or is not
281 valid (i.e, it has been deallocated or freed or never initialized)
282 Note that an overflow page will be returned since it is a valid page.
283
284 @exception StandardException Standard Cloudscape error policy
285 */
286 public Page getPage(long pageNumber)
287 throws StandardException;
288
289 /**
290 Identical to getPage but returns null immediately if the desired page
291 is already latched by another Container.
292
293 @return the required Page or null if the page does not exist or the page
294 is already latched.
295
296 @exception StandardException Standard Cloudscape error policy
297
298 */
299 public Page getPageNoWait(long pageNumber) throws StandardException;
300
301 /**
302 Obtain exclusive access to the page with the given page number.
303
304 Will only return a valid, non-overflow user page - so can be used by
305 routines in post commit to get pages to attempt deleted row space
306 reclamation. If for some reason a request is made for an overflow
307 page a null will be returned.
308
309 Once the Page is no longer required the Page's unlatch() method must
310 be called.
311
312 <P>
313 The Page object is guaranteed to remain in-memory and exclusive to the
314 caller until its unlatch() method is called.
315
316 @return the required Page or null if the page does not exist or is not
317 valid (i.e, it has been deallocated, freed, never initialized, or is
318 an allocation page or overflow page)
319
320 @exception StandardException Standard Cloudscape error policy
321 */
322 public Page getUserPageNoWait(long pageNumber) throws StandardException;
323 /**
324 Obtain exclusive access to the page with the given page number.
325
326 Will only return a valid, non-overflow user page - so can be used by
327 routines in post commit to get pages to attempt deleted row space
328 reclamation. If for some reason a request is made for an overflow
329 page a null will be returned.
330
331 Once the Page is no longer required the Page's unlatch() method must
332 be called.
333
334 <P>
335 The Page object is guaranteed to remain in-memory and exclusive to the
336 caller until its unlatch() method is called.
337
338 @return the required Page or null if the page does not exist or is not
339 valid (i.e, it has been deallocated, freed, never initialized, or is
340 an allocation page or overflow page)
341
342 @exception StandardException Standard Cloudscape error policy
343 */
344 public Page getUserPageWait(long pageNumber) throws StandardException;
345
346 /**
347 Obtain exclusive access to the current first page of the container.
348 Only a valid, non overflow page will be returned.
349 Pages in the container are ordered in an internally defined ordering.
350 <P>
351 Note that once this method returns this page may no longer be the
352 first page of the container. I.e, other threads may allocate pages
353 prior to this page number while this page is latched. It is up to
354 the caller of this routine to synchronize this call with addPage to
355 assure that this is the first page.
356 <BR>
357 As long as the client provide the necessary lock to ensure
358 that no addPage is called, then this page is guaranteed to be the
359 first page of the container in some internally defined ordering of
360 the pages.
361
362 @return latched page or null if there is no page in the container
363 @exception StandardException Standard Cloudscape error policy
364
365 @see ContainerHandle#getPage
366 */
367 public Page getFirstPage() throws StandardException;
368
369 /**
370 Obtain exclusive access to the next valid page of the given page number
371 in the container. Only a valid, non overflow page will be returned.
372 Pages in the container are ordered in an internally defined ordering.
373 <P>
374 Note that once this method returns this page may no longer be the
375 next page of the container. I.e, other threads may allocate pages
376 prior to this page number while this page is latched. It is up to
377 the caller of this routine to synchronize this call with addPage to
378 assure that this is the first page.
379 <BR>
380 As long as the client provide the necessary lock to ensure
381 that no addPage is called, then this page is guaranteed to be the
382 next page of the container in some internally defined ordering of
383 the pages.
384 <BR>
385 If no pages are added or removed, then an iteration such as:
386 <PRE>
387 for (Page p = containerHandle.getFirstPage();
388 p != null;
389 p = containerHandle.getNextPage(p.getPageNumber()))
390 <PRE>
391 will guarentee to iterate thru and latched all the valid pages
392 in the container
393
394 @param prevNum the pagenumber of the page previous to the page
395 that is to be gotten. The page which correspond to prevNum
396 may or may not be latched by the caller, but it must be gotten
397 via a page which was (or currently still is) latched, and the page
398 number must be gotten while the container must not have been closed
399 or dropped or removed in the interim.
400
401 In other words, if the user manufactures a page number, or remembers
402 the page number from a previous session or a previous openContainer,
403 then the behavior of this routine is undefined.
404
405 @return latched page or null if there is no next page in the container
406 @exception StandardException Standard Cloudscape error policy
407
408 @see ContainerHandle#getPage
409 */
410 public Page getNextPage(long prevNum) throws StandardException;
411
412
413 /**
414 Get a page for insert. If RawStore thinks it knows where a potentially
415 suitable page is for insert, it will return it. If RawStore doesn't
416 know where a suitable page for insert is, or if there are no allocated
417 page, then null is returned. If a page is returned, it will be a
418 valid, non-overflow page. A potentially suitable page is one which
419 has enough space for a minium sized record.
420
421 @return a valid, non-overflow page. Or null if RawStore doesn't know
422 where to find a good valid, non-overflow page.
423
424 @param flag a GET_PAGE_* flag.
425
426 @exception StandardException Standard Cloudscape error policy
427 */
428 public Page getPageForInsert(int flag)
429 throws StandardException;
430
431 public Page getPageForCompress(
432 int flag,
433 long pageno)
434 throws StandardException;
435
436 // Try to get a page that is unfilled, 'unfill-ness' is defined by the
437 // page. Since unfill-ness is defined by the page, the only thing RawStore
438 // guarentees about the page is that it has space for a a minimum sized
439 // record.
440 //
441 // If this bit is not set, then getPageForInsert will get the page that was
442 // last gotten, provided it has space for a minimum sized record.
443 //
444 // If for whatever reasons RawStore is unable to come up with such a page,
445 // null will be returned.
446 public static final int GET_PAGE_UNFILLED = 0x1;
447
448
449 /**
450 * Request the system properties associated with a container.
451 * <p>
452 * Request the value of properties that are associated with a table. The
453 * following properties can be requested:
454 * derby.storage.pageSize
455 * derby.storage.pageReservedSpace
456 * derby.storage.minimumRecordSize
457 * <p>
458 * To get the value of a particular property add it to the property list,
459 * and on return the value of the property will be set to it's current
460 * value. For example:
461 *
462 * get_prop(ConglomerateController cc)
463 * {
464 * Properties prop = new Properties();
465 * prop.put("derby.storage.pageSize", "");
466 * cc.getTableProperties(prop);
467 *
468 * System.out.println(
469 * "table's page size = " +
470 * prop.getProperty("derby.storage.pageSize");
471 * }
472 *
473 * @param prop Property list to fill in.
474 *
475 * @exception StandardException Standard exception policy.
476 **/
477 void getContainerProperties(Properties prop)
478 throws StandardException;
479
480 /**
481 Close me. After using this method the caller must throw away the
482 reference to the Container object, e.g.
483 <PRE>
484 ref.close();
485 ref = null;
486 </PRE>
487 <BR>
488 The container will be closed automatically at the commit or abort
489 of the transaction if this method is not called explictly.
490 <BR>
491 Any pages that were obtained using me and have not been released
492 using Page's unlatch method are released, and references to them must be
493 thrown away.
494
495
496 @see Page#unlatch
497 @see Page#fetch
498 */
499 public void close();
500
501 /**
502 Cost estimation
503 */
504
505 /**
506 Get the total estimated number of rows in the container, not including
507 overflow rows. This number is a rough estimate and may be grossly off.
508
509 @param flag different flavors of row count (reserved for future use)
510 @exception StandardException Standard Cloudscape error policy
511 */
512 public long getEstimatedRowCount(int flag) throws StandardException;
513
514 /**
515 Set the total estimated number of rows in the container. Often, after
516 a scan, the client of RawStore has a much better estimate of the number
517 of rows in the container then what RawStore has. Use this better
518 number for future reference.
519 <BR>
520 It is OK for a ReadOnly ContainerHandle to set the estimated row count.
521
522 @param count the estimated number of rows in the container.
523 @param flag different flavors of row count (reserved for future use)
524
525 @exception StandardException Standard Cloudscape error policy
526 */
527 public void setEstimatedRowCount(long count, int flag) throws StandardException;
528
529 /**
530 Get the total estimated number of allocated (not freed, not
531 deallocated) user pages in the container, including overflow pages.
532 this number is a rough estimate and may be grossly off.
533
534 @param flag different flavors of page count (reserved for future use)
535
536 @exception StandardException Standard Cloudscape error policy
537 */
538 public long getEstimatedPageCount(int flag) throws StandardException;
539
540
541 /**
542 Flush all dirty pages of the container to disk. Used mainly for
543 UNLOGGED or CREATE_UNLOGGED operation.
544
545 @exception StandardException Standard Cloudscape error policy
546 */
547 public void flushContainer() throws StandardException;
548
549 /**
550 Return the locking policy for this open container.
551 */
552 public LockingPolicy getLockingPolicy();
553
554 /**
555 Set the locking policy for this open container
556 */
557 public void setLockingPolicy(LockingPolicy newLockingPolicy);
558
559 /**
560 Return a record handle that is initialized to the given segment id,
561 container id, page number and record id.
562
563 @exception StandardException Standard cloudscape exception policy.
564
565 @param pageNumber the page number of the RecordHandle.
566 @param recordId the record id of the RecordHandle.
567
568 @see RecordHandle
569 */
570 public RecordHandle makeRecordHandle(long pageNumber, int recordId)
571 throws StandardException;
572
573
574 /**
575 This record probably has shrunk considerably. Free its reserved space
576 or compact it.
577
578 @param record The record handle, the record must have been locked execlusively already.
579 @exception StandardException Standard cloudscape exception policy.
580 */
581 public void compactRecord(RecordHandle record) throws StandardException;
582
583 /**
584 Return true if this containerHandle refers to a temporary container.
585 @exception StandardException Standard cloudscape exception policy.
586 */
587 public boolean isTemporaryContainer() throws StandardException;
588
589 /**
590 Get information about space used by the container.
591 **/
592 public SpaceInfo getSpaceInfo() throws StandardException;
593
594 }