001: /*
002:
003: Derby - Class org.apache.derby.iapi.store.raw.ContainerHandle
004:
005: Licensed to the Apache Software Foundation (ASF) under one or more
006: contributor license agreements. See the NOTICE file distributed with
007: this work for additional information regarding copyright ownership.
008: The ASF licenses this file to you under the Apache License, Version 2.0
009: (the "License"); you may not use this file except in compliance with
010: the License. You may obtain a copy of the License at
011:
012: http://www.apache.org/licenses/LICENSE-2.0
013:
014: Unless required by applicable law or agreed to in writing, software
015: distributed under the License is distributed on an "AS IS" BASIS,
016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: See the License for the specific language governing permissions and
018: limitations under the License.
019:
020: */
021:
022: package org.apache.derby.iapi.store.raw;
023:
024: import org.apache.derby.iapi.store.access.SpaceInfo;
025: import org.apache.derby.iapi.error.StandardException;
026:
027: import java.util.Properties;
028:
029: /**
030: A Container contains a contigious address space of pages, the pages
031: start at page number Container.FIRST_PAGE_NUMBER and are numbered sequentially.
032:
033: The page size is set at addContainer() time.
034:
035:
036: RESOLVE: this style of coding is not currently enforced
037: If the caller calls getPage (or one of its variants) more than once on the
038: same page, the caller must call unlatch a corresponding number of times in
039: order to ensure that the page is latched. For example:
040: <p>
041: <blockquote><pre>
042: Container c;
043: Page p1 = c.getPage(Container.FIRST_PAGE_NUMBER);
044: Page p2 = c.getPage(Container.FIRST_PAGE_NUMBER);
045: p1.unlatch(); -- Page is still latched.
046: p2.unlatch(); -- Page is now unlatched.
047: </pre></blockquote>
048:
049: <p>
050: There is no restriction on the order in which latching and unlatching is
051: done. In the example, p1 could have been unlatched after p2 with no ill
052: effects.
053:
054: <P> <B>Open container modes</B>
055: ContainerHandle.MODE are used to open or create the container.
056: Unlike TableProperties, MODEs are not permanantely associated with the
057: container, it is effective only for the lifetime of the containerHandle
058: itself.
059: <BR>A container may use any of these mode flags when it is opened.
060: <UL>
061: <LI>MODE_READONLY - Open the container in read only mode.
062: <LI>MODE_FORUPDATE - Open the container in update mode, if the underlying
063: storage does not allow updates
064: then the container will be opned in read only mode.
065: <LI>MODE_UNLOGGED - If Unset, any changes to the container are logged.
066: If set, any user changes to the container are unlogged. It is guaranteed
067: at commit time that all changes made during the transaction will have been
068: flushed to disk. Using this mode automatically opens the container in
069: container locking, isolation 3 level. The state of the container following
070: an abort or any type of rollback is unspecified.
071: <LI>MODE_CREATE_UNLOGGED - If set, not only are user changes to the
072: container are unlogged, page allocations are also unlogged. This MODE is
073: only useful for container is created in the same statement and no change on
074: the container (other than the create) is ever logged. The difference
075: between MODE_UNLOGGED and MODE_CREATE_UNLOGGED is that page allocation is
076: also unlogged and commit of nested transaction will not cause the container
077: to be forced from the cache. Unlike MODE_UNLOGGED, MODE_CREATE_UNLOGGED
078: does not force the cache. It is up to the client of raw store to force the
079: cache at the appropriate time - this allows a statement to create and open
080: the container serveral times for bulk loading without logging or doing any
081: synchronous I/O.
082: <LI>MODE_LOCK_NOWAIT - if set, then don't wait for the container lock, else
083: wait for the container lock. This flag only dictates whether the lock
084: should be waited for or not. After the container is successfully opened,
085: whether this bit is set or not has no effect on the container handle.
086: </UL>
087: If neither or both of the {MODE_READONLY, MODE_FORUPDATE} modes are
088: specified then the behaviour of the container is unspecified.
089: <BR>
090: MODE_UNLOGGED must be set for MODE_CREATE_UNLOGGED to be set.
091: <P>
092: <B>Temporary Containers</B><BR>
093: If when creating a container the segment used is
094: ContainerHandle.TEMPORARY_SEGMENT then the container is a temporary
095: container. Temporary containers are not logged or locked and do not live
096: across re-boots of the system. In addition any abort or rollback including
097: rollbacks to savepoints truncate the container if it has been opened for
098: update since the last commit or abort. Temporary containers are private
099: to a transaction and must only be used a single thread within the
100: transaction at any time, these restrictions are not currently enforced.
101: <BR>
102: When opening a temporary container for update access these additional mode
103: flags may be used
104: <UL>
105: <LI> MODE_TRUNCATE_ON_COMMIT - At commit/abort time container is truncated.
106: <LI> MODE_DROP_ON_COMMIT - At commit/abort time the container is dropped.
107: <LI> MODE_TEMP_IS_KEPT - At commit/abort time the container is kept around.
108: </UL>
109: If a temporary container is opened multiple times in the same transaction
110: with different modes then the most severe mode is used, ie. none <
111: truncate on commit < drop on commit.
112: The MODE_UNLOGGED, MODE_CREAT_UNLOGGED flags are ignored when opening a
113: temporary container, not logged is always assumed. */
114:
115: public interface ContainerHandle {
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: The first valid page number
151: */
152: public static final long FIRST_PAGE_NUMBER = 1;
153:
154: /**
155: A page number that is guaranteed to be invalid.
156: */
157: public static final long INVALID_PAGE_NUMBER = -1;
158:
159: /**
160: Return my identifier.
161: */
162: public ContainerKey getId();
163:
164: /**
165: Return my unique identifier, this identifier will be unique to each
166: instance of an open container handle. This id is used by the locking
167: system to group locks to an open container handle.
168: */
169: public Object getUniqueId();
170:
171: /**
172: * Is the container opened for read only or update?
173: *
174: * @return true if container is opened for read only, else false.
175: **/
176: boolean isReadOnly();
177:
178: /**
179: Add an empty page to the container and obtain exclusive access to it.
180: <P>
181: Note that the added page may not be the last page in the Container.
182:
183: Once the Page is no longer required the Page's unlatch() method must
184: be called.
185:
186: @return a reference to the page that was added.
187:
188: @see Page#unlatch
189:
190: @exception StandardException Standard Cloudscape error policy
191: @exception StandardException If a page could not be allocated.
192: */
193: public Page addPage() throws StandardException;
194:
195: /**
196: Release free space to the OS.
197: <P>
198: As is possible release any free space to the operating system. This
199: will usually mean releasing any free pages located at the end of the
200: file using the java truncate() interface.
201:
202: @exception StandardException Standard Cloudscape error policy
203: */
204: public void compressContainer() throws StandardException;
205:
206: /**
207: * Get the reusable recordId sequence number.
208: * @return version sequence number
209: * @exception StandardException Standard Derby error policy
210: */
211: public long getReusableRecordIdSequenceNumber()
212: throws StandardException;
213:
214: /**
215: Add an empty page to the container and obtain exclusive access to it.
216: <P>
217: If flag == ADD_PAGE_DEFAULT, this call is identical to addPage().
218: <BR>
219: If flag == ADD_PAGE_BULK, then this call signifies to the container that
220: this addPage is part of a large number of additional pages and it is
221: desirable to do whatever possible to facilitate adding many subsequent pages.
222: The actual container implementation will decide whether or not to heed
223: this hint and what to do about it.
224:
225: @return a reference to the page that was added.
226:
227: @see Page#unlatch
228:
229: @exception StandardException Standard Cloudscape error policy
230: @exception StandardException If a page could not be allocated.
231:
232: */
233: public Page addPage(int flag) throws StandardException;
234:
235: public static final int ADD_PAGE_DEFAULT = 0x1;
236: public static final int ADD_PAGE_BULK = 0x2;
237:
238: /**
239: Try to preallocate numPage new pages if possible.
240: */
241: public void preAllocate(int numPage);
242:
243: /**
244: Remove this page from the container and unlatch the page. <B>Caller
245: should commit or abort this transaction ASAP because failure to do so
246: will slow down page allocation of this container. </B>
247:
248: <BR>The page to be removed must be latched and gotten (or added) by
249: this ContainerHandle. The page should not be used again after this
250: call as if it has been unlatched. If the call to removePage is
251: successful, this page is invalid should not be gotten again with
252: getPage.
253:
254: <BR>RemovePage will guarantee to unlatch the page even if a
255: StandardException is thrown.
256:
257: <P>
258: <B>Locking Policy</B>
259: <BR>
260: The page will not be freed until the transaction that removed the page
261: commits. A special RecordHandle.DEALLOC_PROTECTION_HANDLE lock will be
262: gotten for the transaction and which is used to prevent the page from
263: being freed. This lock will be held regardless of the default locking
264: policy of the transaction that called removedPage.
265:
266: @see LockingPolicy
267: @see RecordHandle
268:
269: @exception StandardException Standard Cloudscape error policy
270: */
271: public void removePage(Page page) throws StandardException;
272:
273: /**
274: Obtain exclusive access to the page with the given page number.
275:
276: Once the Page is no longer required the Page's unlatch() method must
277: be called.
278:
279: <P>
280: The Page object is guaranteed to remain in-memory and exclusive to the
281: caller until its unlatch() method is called.
282:
283: @return the required Page or null if the page does not exist or is not
284: valid (i.e, it has been deallocated or freed or never initialized)
285: Note that an overflow page will be returned since it is a valid page.
286:
287: @exception StandardException Standard Cloudscape error policy
288: */
289: public Page getPage(long pageNumber) throws StandardException;
290:
291: /**
292: Identical to getPage but returns null immediately if the desired page
293: is already latched by another Container.
294:
295: @return the required Page or null if the page does not exist or the page
296: is already latched.
297:
298: @exception StandardException Standard Cloudscape error policy
299:
300: */
301: public Page getPageNoWait(long pageNumber) throws StandardException;
302:
303: /**
304: Obtain exclusive access to the page with the given page number.
305:
306: Will only return a valid, non-overflow user page - so can be used by
307: routines in post commit to get pages to attempt deleted row space
308: reclamation. If for some reason a request is made for an overflow
309: page a null will be returned.
310:
311: Once the Page is no longer required the Page's unlatch() method must
312: be called.
313:
314: <P>
315: The Page object is guaranteed to remain in-memory and exclusive to the
316: caller until its unlatch() method is called.
317:
318: @return the required Page or null if the page does not exist or is not
319: valid (i.e, it has been deallocated, freed, never initialized, or is
320: an allocation page or overflow page)
321:
322: @exception StandardException Standard Cloudscape error policy
323: */
324: public Page getUserPageNoWait(long pageNumber)
325: throws StandardException;
326:
327: /**
328: Obtain exclusive access to the page with the given page number.
329:
330: Will only return a valid, non-overflow user page - so can be used by
331: routines in post commit to get pages to attempt deleted row space
332: reclamation. If for some reason a request is made for an overflow
333: page a null will be returned.
334:
335: Once the Page is no longer required the Page's unlatch() method must
336: be called.
337:
338: <P>
339: The Page object is guaranteed to remain in-memory and exclusive to the
340: caller until its unlatch() method is called.
341:
342: @return the required Page or null if the page does not exist or is not
343: valid (i.e, it has been deallocated, freed, never initialized, or is
344: an allocation page or overflow page)
345:
346: @exception StandardException Standard Cloudscape error policy
347: */
348: public Page getUserPageWait(long pageNumber)
349: throws StandardException;
350:
351: /**
352: Obtain exclusive access to the current first page of the container.
353: Only a valid, non overflow page will be returned.
354: Pages in the container are ordered in an internally defined ordering.
355: <P>
356: Note that once this method returns this page may no longer be the
357: first page of the container. I.e, other threads may allocate pages
358: prior to this page number while this page is latched. It is up to
359: the caller of this routine to synchronize this call with addPage to
360: assure that this is the first page.
361: <BR>
362: As long as the client provide the necessary lock to ensure
363: that no addPage is called, then this page is guaranteed to be the
364: first page of the container in some internally defined ordering of
365: the pages.
366:
367: @return latched page or null if there is no page in the container
368: @exception StandardException Standard Cloudscape error policy
369:
370: @see ContainerHandle#getPage
371: */
372: public Page getFirstPage() throws StandardException;
373:
374: /**
375: Obtain exclusive access to the next valid page of the given page number
376: in the container. Only a valid, non overflow page will be returned.
377: Pages in the container are ordered in an internally defined ordering.
378: <P>
379: Note that once this method returns this page may no longer be the
380: next page of the container. I.e, other threads may allocate pages
381: prior to this page number while this page is latched. It is up to
382: the caller of this routine to synchronize this call with addPage to
383: assure that this is the first page.
384: <BR>
385: As long as the client provide the necessary lock to ensure
386: that no addPage is called, then this page is guaranteed to be the
387: next page of the container in some internally defined ordering of
388: the pages.
389: <BR>
390: If no pages are added or removed, then an iteration such as:
391: <PRE>
392: for (Page p = containerHandle.getFirstPage();
393: p != null;
394: p = containerHandle.getNextPage(p.getPageNumber()))
395: <PRE>
396: will guarentee to iterate thru and latched all the valid pages
397: in the container
398:
399: @param prevNum the pagenumber of the page previous to the page
400: that is to be gotten. The page which correspond to prevNum
401: may or may not be latched by the caller, but it must be gotten
402: via a page which was (or currently still is) latched, and the page
403: number must be gotten while the container must not have been closed
404: or dropped or removed in the interim.
405:
406: In other words, if the user manufactures a page number, or remembers
407: the page number from a previous session or a previous openContainer,
408: then the behavior of this routine is undefined.
409:
410: @return latched page or null if there is no next page in the container
411: @exception StandardException Standard Cloudscape error policy
412:
413: @see ContainerHandle#getPage
414: */
415: public Page getNextPage(long prevNum) throws StandardException;
416:
417: /**
418: Get a page for insert. If RawStore thinks it knows where a potentially
419: suitable page is for insert, it will return it. If RawStore doesn't
420: know where a suitable page for insert is, or if there are no allocated
421: page, then null is returned. If a page is returned, it will be a
422: valid, non-overflow page. A potentially suitable page is one which
423: has enough space for a minium sized record.
424:
425: @return a valid, non-overflow page. Or null if RawStore doesn't know
426: where to find a good valid, non-overflow page.
427:
428: @param flag a GET_PAGE_* flag.
429:
430: @exception StandardException Standard Cloudscape error policy
431: */
432: public Page getPageForInsert(int flag) throws StandardException;
433:
434: public Page getPageForCompress(int flag, long pageno)
435: throws StandardException;
436:
437: // Try to get a page that is unfilled, 'unfill-ness' is defined by the
438: // page. Since unfill-ness is defined by the page, the only thing RawStore
439: // guarentees about the page is that it has space for a a minimum sized
440: // record.
441: //
442: // If this bit is not set, then getPageForInsert will get the page that was
443: // last gotten, provided it has space for a minimum sized record.
444: //
445: // If for whatever reasons RawStore is unable to come up with such a page,
446: // null will be returned.
447: public static final int GET_PAGE_UNFILLED = 0x1;
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)
528: throws StandardException;
529:
530: /**
531: Get the total estimated number of allocated (not freed, not
532: deallocated) user pages in the container, including overflow pages.
533: this number is a rough estimate and may be grossly off.
534:
535: @param flag different flavors of page count (reserved for future use)
536:
537: @exception StandardException Standard Cloudscape error policy
538: */
539: public long getEstimatedPageCount(int flag)
540: throws StandardException;
541:
542: /**
543: Flush all dirty pages of the container to disk. Used mainly for
544: UNLOGGED or CREATE_UNLOGGED operation.
545:
546: @exception StandardException Standard Cloudscape error policy
547: */
548: public void flushContainer() throws StandardException;
549:
550: /**
551: Return the locking policy for this open container.
552: */
553: public LockingPolicy getLockingPolicy();
554:
555: /**
556: Set the locking policy for this open container
557: */
558: public void setLockingPolicy(LockingPolicy newLockingPolicy);
559:
560: /**
561: Return a record handle that is initialized to the given segment id,
562: container id, page number and record id.
563:
564: @exception StandardException Standard cloudscape exception policy.
565:
566: @param pageNumber the page number of the RecordHandle.
567: @param recordId the record id of the RecordHandle.
568:
569: @see RecordHandle
570: */
571: public RecordHandle makeRecordHandle(long pageNumber, int recordId)
572: throws StandardException;
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)
582: throws StandardException;
583:
584: /**
585: Return true if this containerHandle refers to a temporary container.
586: @exception StandardException Standard cloudscape exception policy.
587: */
588: public boolean isTemporaryContainer() throws StandardException;
589:
590: /**
591: Get information about space used by the container.
592: **/
593: public SpaceInfo getSpaceInfo() throws StandardException;
594:
595: /**
596: Backup the container to the specified path.
597: @exception StandardException Standard Cloudscape error policy
598: */
599: public void backupContainer(String backupContainerPath)
600: throws StandardException;
601: }
|