Source code: org/apache/derby/iapi/store/raw/Page.java
1 /*
2
3 Derby - Class org.apache.derby.iapi.store.raw.Page
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.services.io.FormatableBitSet;
24
25 import org.apache.derby.iapi.error.StandardException;
26
27 import org.apache.derby.iapi.store.access.conglomerate.LogicalUndo;
28
29 import org.apache.derby.iapi.store.access.Qualifier;
30
31 import org.apache.derby.iapi.types.DataValueDescriptor;
32
33
34 /**
35 A Page contains an ordered set of records which are the stored form of rows.
36 A record is a stream of bytes created from a row array. The record
37 contains one or more fields, fields have a one to one correlation with
38 the DataValueDescriptor's contained within a row array.
39 <P>
40 A Page represents <B>exclusive</B> access to a data page within a container.
41 Exclusive access is released by calling the unlatch() method, once that
42 occurs the caller must no longer use the Page reference.
43 <P>
44 Several of the methods in Page take a RecordHandle as an argument.
45 RecordHandles are obtained from a Page, while holding exclusive access of
46 Page or a from a previous exclusive access of a Page representing the same
47 data page.
48 All RecordHandle's used as arguments to methods (with the exception of
49 recordExists()) must be valid for the current state of the page. If they
50 are not valid then the method will throw an exception. A caller can ensure
51 that a record handle is valid by:
52 <UL>
53 <LI> Obtaining the handle during this exclusive access of this page
54 <LI> Checking the record still exists with the method recordExists()
55 <LI> Not using a handle after a delete().
56 </UL>
57 <P>
58 Several of the methods in Page take a slot number as an argument. A slot
59 always correspond to a record, which may be deleted or undeleted.
60
61 <BR>
62 MT - Latched - In general every method requires the page to be latched.
63
64 <P>
65 <B>Latching</B>
66 <P>
67 All page methods which are not valid for a latched page throw an
68 exception if the page is not latched. [@exception clauses on all
69 the methods should be updated to reflect this].
70
71 <P>
72 <B>Aux Objects</B>
73 <BR>
74 The page cache will manage a client object along with the page as long
75 as it remains in cache. This object is called the "aux object". The
76 aux object is associated with the page with setAuxObject(), and can be
77 retreived later with getAuxObject(). The aux object will remain valid
78 as long as the page is latched, but callers cannot assume that an aux
79 object will ever stick around once the page is unlatched. However, the
80 page manager promises to call pageBeingEvicted() once before clearing
81 the aux reference from the page.
82
83 @see Object
84 @see ContainerHandle
85 @see RecordHandle
86 @see AuxObject
87 */
88
89 public interface Page
90 {
91
92 /**************************************************************************
93 * Constants of the class
94 **************************************************************************
95 */
96
97 /**
98 * The slot number of the first slot. This is guaranteed to be zero.
99 **/
100 public static final int FIRST_SLOT_NUMBER = 0;
101
102 /**
103 * A slot number guaranteed to be invalid.
104 **/
105 public static final int INVALID_SLOT_NUMBER = -1;
106
107 /**
108 * Return the page number of this page.
109 * <p>
110 * Page numbers are unique within a container and start at
111 * ContainerHandle.FIRST_PAGE_NUMBER and increment by 1 regardless of the
112 * page size.
113 * <p>
114 *
115 * <BR> MT - Latched
116 *
117 * @see ContainerHandle
118 *
119 * @return The page number of this page.
120 **/
121 public long getPageNumber();
122
123 /**************************************************************************
124 * Public Methods of This class: record handle interface.
125 * the following interfaces to page use the record Id or record handle
126 * (rather than the slot interface).
127 **************************************************************************
128 */
129
130 /**
131 * Return an invalid record handle.
132 * <p>
133 *
134 * @return an invalid record handle.
135 *
136 * @exception StandardException Standard exception policy.
137 **/
138 public RecordHandle getInvalidRecordHandle();
139
140 /**
141 * Return a record handle for the given constant record id.
142 * <p>
143 * Return a record handle that doesn't represent a record but rather has
144 * a special meaning. Used for special cases like creating a key
145 * specific to the page, but not specific to a row on the page.
146 * <p>
147 * See RecordHandle interface for a list of "special record handles."
148 *
149 * @see RecordHandle
150 *
151 * @return The created record handle.
152 *
153 * @param recordHandleConstant the special recordId
154 *
155 * @exception StandardException if input is not a special record identifier.
156 **/
157 public RecordHandle makeRecordHandle(int recordHandleConstant)
158 throws StandardException;
159
160 /**
161 * Get a record handle from a previously stored record id.
162 * <p>
163 * Get a record handle from a previously stored record identifier that was
164 * obtained from a RecordHandle.
165 * <p>
166 * <BR> MT - Latched
167 *
168 * @return A valid record handle or null if the record no longer exists.
169 *
170 * @param recordId previously stored recordId.
171 *
172 * @see RecordHandle#getId
173 **/
174 RecordHandle getRecordHandle(int recordId);
175
176 /**
177 * does the record still exist on the page?
178 * <p>
179 * If "ignoreDelete" is true and the record handle represents a record on
180 * the page (either marked deleted or not) return true. If "ignoreDelete"
181 * is false return true if the record handle represents a record on the
182 * page and the record is not marked as deleted. Return false otherwise.
183 *
184 * <BR> MT - Latched
185 *
186 * @return boolean indicating if the record still exists on the page.
187 *
188 * @param handle handle of the record to look for.
189 * @param ignoreDelete if true, then routine will return true even if the
190 * row is marked deleted.
191 *
192 * @exception StandardException Standard exception policy.
193 **/
194 boolean recordExists(RecordHandle handle, boolean ignoreDelete)
195 throws StandardException;
196
197 /**
198 * Fetch and lock a non-deleted record.
199 * <p>
200 * Lock and fetch a non-deleted record identified by a RecordHandle.
201 * Reads data from the page into row.
202 * <P>
203 * <B>Locking Policy</B>
204 * <BR>
205 * Calls the lockRecordForRead() method of the LockingPolicy object
206 * passed to the openContainer() call before the record is accessed.
207 * <BR>
208 * The page latch may be released and re-latched within this method.
209 * This will occur if the record lock has to be waited for.
210 *
211 * @param handle Handle to record.
212 * @param row Row to be filled in with data from the record.
213 * @param validColumns a bit map of which columns in the row is to be
214 * fetched. ValidColumns will not be changed by
215 * RawStore.
216 * @param forUpdate true if the intention is to update this record,
217 * false otherwise.
218 *
219 * @return A handle to the record, null if the record has been deleted.
220 *
221 * @exception StandardException Standard Cloudscape error policy,
222 * a statemente level exception is thrown if
223 * the record handle does not match a record
224 * on the page.
225 *
226 * @see Page#delete
227 * @see LockingPolicy
228 **/
229 RecordHandle fetch(
230 RecordHandle handle,
231 Object[] row,
232 FormatableBitSet validColumns,
233 boolean forUpdate)
234 throws StandardException;
235
236 /**
237 * Is it likely that an insert will fit on this page?
238 * <p>
239 * Return true if there is a good chance an insert will fit on this page,
240 * false otherwise. If this returns true then an insert may still fail by
241 * throwing an exception or by returning null, see insertAtSlot for details.
242 * It is very probable that this call is much faster than the version that
243 * takes a row. In situations where it is expected that the
244 * majority of times a row will fit on a page this method should be used
245 * and the null return handled from insert/insertAtSlot.
246 *
247 * <BR>
248 * MT - latched
249 *
250 * @return true if it is likely an insert will fit on the page.
251 *
252 * @exception StandardException Standard exception policy.
253 **/
254 boolean spaceForInsert()
255 throws StandardException;
256
257 /**
258 * will insert of this row fit on this page?
259 * <p>
260 * Return true if this record is guaranteed to be inserted successfully
261 * using insert() or insertAtSlot(). This guarantee is only valid if the
262 * following conditions are fulfilled before an insert is called with t
263 * his row.
264 * <UL>
265 * <LI> The page is not unlatched
266 * <LI> The page is not modified in any way, ie. no updates or other inserts
267 * <LI> The row is not modified in such a way that would change its
268 * storage size
269 * </UL>
270 *
271 * <BR>
272 * MT - latched
273 *
274 * @return true if insert of this row will fit on this page.
275 *
276 * @param row The row to check for insert.
277 * @param validColumns bit map to interpret valid columns in row.
278 * @param overflowThreshold The percentage of the page to use for the
279 * insert. 100 means use 100% of the page,
280 * 50 means use 50% of page (ie. make sure
281 * 2 rows fit per page).
282 *
283 * @exception StandardException Standard exception policy.
284 **/
285 boolean spaceForInsert(
286 Object[] row,
287 FormatableBitSet validColumns,
288 int overflowThreshold)
289 throws StandardException;
290
291 /**
292 * Insert a record anywhere on the page.
293 * <P>
294 *
295 * <B>Locking Policy</B>
296 * <BR>
297 * Calls the lockRecordForWrite() method of the LockingPolicy object
298 * passed to the openContainer() call before the record is inserted.
299 * <BR>
300 * MT - latched
301 *
302 * @param row The row version of the data
303 * @param validColumns a bit map of which columns in the row is valid.
304 * ValidColumns will not be changed by RawStore.
305 * @param insertFlag see values for insertFlag below.
306 *
307 * @return A RecordHandle representing the new record.
308 *
309 * @exception StandardException Standard Cloudscape error policy
310 * @exception StandardException The container was not opened in update mode.
311 * @exception StandardException Row cannot fit on the page or row is null.
312 **/
313 RecordHandle insert(
314 Object[] row,
315 FormatableBitSet validColumns,
316 byte insertFlag,
317 int overflowThreshold)
318 throws StandardException;
319
320 /**
321 Update the complete record identified by the record handle.
322
323 */
324 /**
325 * Update the record identified by the record handle.
326 * <p>
327 * Update the record, the new column values are found in row[] and if
328 * validColumns is not-null, only use the columns indicated as valid in
329 * the bit set.
330 * <p>
331 * <BR>
332 * The page latch may be released and re-latched within this method.
333 * This will occur if the record lock has to be waited for.
334 *
335 * @param handle the record handle
336 * @param row The row version of the data
337 * @param validColumns A bit map of which columns in the row is valid.
338 * ValidColumns will not be changed by RawStore.
339 *
340 * @return true if the record is updated.
341 * False if it is not because the record is already deleted.
342 *
343 * @exception StandardException Standard Cloudscape error policy
344 * @exception StandardException The container was not opened in update mode.
345 * @exception StandardException If the record handle does not match
346 * a record on the page.
347 *
348 * @see Page#updateAtSlot
349 *
350 * @exception StandardException Standard exception policy.
351 **/
352 boolean update(
353 RecordHandle handle,
354 Object[] row,
355 FormatableBitSet validColumns)
356 throws StandardException;
357
358 /**
359 * Mark the record identified by position as deleted.
360 * <p>
361 * Mark the record identified by position as deleted. The record may be
362 * undeleted sometime later using undelete() by any transaction that sees
363 * the record.
364 * <p>
365 * <B>Locking Policy</B>
366 * <P>
367 * Calls the lockRecordForWrite() method of the LockingPolicy object
368 * passed to the openContainer() call before the record is deleted.
369 *
370 * <BR>
371 * The page latch may be released and re-latched within this method.
372 * This will occur if the record lock has to be waited for.
373 *
374 * @param handle record Handle to record
375 * @param undo if logical undo may be necessary, a function pointer to
376 * the access code where the logical undo logic resides.
377 * Null if logical undo is not necessary.
378 *
379 * @return true if the record was updated.
380 * False if it wasn't because it is already deleted.
381 *
382 * @exception StandardException Standard Cloudscape error policy
383 * @exception StandardException The container was not opened in update mode.
384 * @exception StandardException If the record handle does not match
385 * a record on the page.
386 *
387 * @see Page#deleteAtSlot
388 * @see LockingPolicy
389 **/
390 public boolean delete(
391 RecordHandle handle,
392 LogicalUndo undo)
393 throws StandardException;
394
395 /**
396 * Move record to a page toward the beginning of the file.
397 * <p>
398 * As part of compressing the table records need to be moved from the
399 * end of the file toward the beginning of the file. Only the
400 * contiguous set of free pages at the very end of the file can
401 * be given back to the OS. This call is used to purge the row from
402 * the current page, insert it into a previous page, and return the
403 * new row location
404 * Mark the record identified by position as deleted. The record may be
405 * undeleted sometime later using undelete() by any transaction that sees
406 * the record.
407 * <p>
408 * The interface is optimized to work on a number of rows at a time,
409 * optimally processing all rows on the page at once. The call will
410 * process either all rows on the page, or the number of slots in the
411 * input arrays - whichever is smaller.
412 * <B>Locking Policy</B>
413 * <P>
414 * MUST be called with table locked, not locks are requested. Because
415 * it is called with table locks the call will go ahead and purge any
416 * row which is marked deleted. It will also use purge rather than
417 * delete to remove the old row after it moves it to a new page. This
418 * is ok since the table lock insures that no other transaction will
419 * use space on the table before this transaction commits.
420 *
421 * <BR>
422 * A page latch on the new page will be requested and released.
423 *
424 * @param slot Slot of row to move.
425 * @param row A template to read the current row into as part
426 * of moving it.
427 * @param old_handle An array to be filled in by the call with the
428 * old handles of all rows moved.
429 * @param new_handle An array to be filled in by the call with the
430 * new handles of all rows moved.
431 *
432 * @return the number of rows processed.
433 *
434 * @exception StandardException Standard Cloudscape error policy
435 *
436 * @see LockingPolicy
437 **/
438 public int moveRecordForCompressAtSlot(
439 int slot,
440 Object[] row,
441 RecordHandle[] old_handle,
442 RecordHandle[] new_handle)
443 throws StandardException;
444
445 /**
446 * Fetch the number of fields in a record.
447 * <p>
448 * <B>Locking Policy</B>
449 * <P>
450 * No locks are obtained.
451 *
452 * <BR>
453 * MT - latched
454 *
455 * @param handle record handle to deleted or non-deleted record
456 *
457 * @return the number of fields in the record
458 *
459 * @exception StandardException Standard Cloudscape error policy, a
460 * statement level exception is thrown if the
461 * record handle does not match a record on
462 * the page.
463 **/
464 public int fetchNumFields(RecordHandle handle)
465 throws StandardException;
466
467 /**************************************************************************
468 * Public Methods of This class: slot interface.
469 * the following interfaces to page use the slot number
470 * (rather than the record handle interface).
471 **************************************************************************
472 */
473
474
475 /**
476 * Get the slot number.
477 * <p>
478 * Get the slot number of a record on a latched page using its record
479 * handle.
480 *
481 * <P><B>Note</B>
482 * The slot number is only good for as long as the page is latched.
483 *
484 * <BR>
485 * MT - latched
486 *
487 * @param handle the record handle
488 *
489 * @return the slot number
490 *
491 * @exception StandardException Standard Cloudscape error policy
492 **/
493 int getSlotNumber(RecordHandle handle)
494 throws StandardException;
495
496 /**
497 * Get the record handle of row at slot.
498 * <p>
499 * Get the record handle of a record on a latched page using its slot
500 * number.
501 *
502 * <BR>
503 * MT - latched
504 *
505 * @param slot the slot number
506 *
507 * @return the record handle.
508 *
509 * @exception StandardException Standard Cloudscape error policy
510 **/
511 RecordHandle getRecordHandleAtSlot(int slot)
512 throws StandardException;
513
514 /**
515 * Find slot for record with an id greater than the passed in identifier.
516 * <p>
517 * Find the slot for the first record on the page with an id greater than
518 * the passed in identifier.
519 *
520 * <BR>
521 * Returns the slot of the first record on the page with an id greater than
522 * the one passed in. Usefulness of this functionality depends on the
523 * client's use of the raw store interfaces. If all "new" records are
524 * always inserted at the end of the page, and the raw store continues to
525 * guarantee that all record id's will be allocated in increasing order on
526 * a given page (assuming a PAGE_REUSABLE_RECORD_ID container), then a page
527 * is always sorted in record id order. For instance current heap tables
528 * function this way. If the client ever inserts at a particular slot
529 * number, rather than at the "end" then the record id's will not be sorted.
530 * <BR>
531 * In the case where all record id's are always sorted on a page, then this
532 * routine can be used by scan's which "lose" their position because the
533 * row they have as a position was purged. They can reposition their scan
534 * at the "next" row after the row that is now missing from the table.
535 * <BR>
536 * This method returns the record regardless of its deleted status.
537 * <BR>
538 * MT - latched
539 *
540 * @param handle record handle to find the next higher id.
541 *
542 * @return record id of the first record on the page with a record id
543 * higher than the one passed in. If no such record exists,
544 * -1 is returned.
545 *
546 * @exception StandardException Standard exception policy.
547 **/
548 int getNextSlotNumber(RecordHandle handle)
549 throws StandardException;
550
551 /**
552 Insert a record at the specified slot.
553 <P>
554 */
555 /**
556 * Insert a record at the specified slot.
557 * <p>
558 * All records that occupy FIRST_SLOT_NUMBER to (slot - 1) are not moved.
559 * <BR>
560 * All records that occupy slot to (recordCount() - 1) are moved up one
561 * slot.
562 * <BR>
563 * The new record is inserted at the specified slot. <BR>
564 * If slot == FIRST_SLOT_NUMBER, then the new record will be inserted at
565 * the first slot. <BR>
566 * If slot == recordCount(), then the record is inserted in a new slot, no
567 * records are moved. <BR>
568 *
569 * If slot is > recordCount() or if slot < FIRST_SLOT_NUMBER, an exception
570 * will be thrown.
571 *
572 * <P><B>Space Policy</B><BR>
573 * If the row will not fit on a page then:
574 * <UL>
575 * <LI> an exception is thrown if the page has no other rows, this is an
576 * indication that the row could never fit on a page in this container.
577 * <LI> null is returned if there are other rows on the page, this is an
578 * indication that the row can potentially be inserted successfully
579 * onto an empty page.
580 * </UL>
581 *
582 * <P>
583 * <B>Locking Policy</B>
584 * <BR>
585 * Calls the lockRecordForWrite() method of the LockingPolicy object passed
586 * to the openContainer() call before the record is inserted.
587 * <BR>
588 * MT - latched
589 *
590 * @param slot The specified slot
591 * @param row The row version of the data
592 * @param undo if logical undo may be necessary, a function pointer
593 * to the access code where the logical undo logic
594 * resides. Null if logical undo is not necessary.
595 * @param validColumns a bit map of which columns in the row is valid.
596 * ValidColumns will not be changed by RawStore.
597 * @param insertFlag if INSERT_UNDO_WITH_PURGE set, then the undo of this
598 * insert will purge the row rather than mark it as
599 * deleted, which is the default bahavior for
600 * insertAtSlot and insert.
601 *
602 * @return A RecordHandle representing the new record, or null if the row
603 * will not fit on a non-empty page.
604 *
605 * @exception StandardException Standard Cloudscape error policy
606 * @exception StandardException The container was not opened in update mode.
607 * @exception StandardException The row cannot fit on the page
608 *
609 * @see LogicalUndo
610 * @see LogicalUndoable
611 **/
612 RecordHandle insertAtSlot(
613 int slot,
614 Object[] row,
615 FormatableBitSet validColumns,
616 LogicalUndo undo,
617 byte insertFlag,
618 int overflowThreshold)
619 throws StandardException;
620
621 /**
622 Values for insertFlag:
623
624 */
625 /**
626 * Values for insertFlag.
627 * <p>
628 *
629 * INSERT_INITIAL - flag initializer
630 *
631 * INSERT_DEFAULT - default insert behavior, if the record does
632 * not fit on the page where the insert
633 * operation is called, an error will be
634 * returned, instead of overflowing the record.
635 *
636 * INSERT_UNDO_WITH_PURGE - if this is set, then the undo of this insert
637 * will purge the row rather than mark it as
638 * deleted, which is the default behaviro for
639 * insertAtSlot and insert.
640 *
641 * INSERT_CONDITIONAL - if this flag is set, then, the overflow is
642 * conditional. The record will be overflowed
643 * only if it exceeds the threshold specified
644 * by the properties, or the parameter.
645 *
646 * INSERT_OVERFLOW - if this flag is set, then the insert
647 * operation will overflow the record if it does
648 * not fit on the page.
649 *
650 * INSERT_FOR_SPLIT - a record is being updated that causes new
651 * portions to be inserted *and* the last new
652 * portion needs to point to an existing portion.
653 *
654 * Rules for the insert flags:
655 * 1. If INSERT_DEFAULT is set, INSERT_CONDITIONAL and INSERT_OVERFLOW
656 * will be ignored
657 * 2. INSERT_UNDO_WITH_PURGE can be set with any of the other 3 flags.
658 * 3. If INSERT_OVERFLOW is not set, INSERT_CONDITIONAL will be ignored.
659 * But, it is not necessary to set INSERT_CONDITIONAL when setting
660 * INSERT_OVERFLOW.
661 * 4. If INSERT_DEFAULT, INSERT_OVERFLOW both are not set, then, default
662 * insert action will be taken, i.e. no overflow will be allowed.
663 **/
664 static final byte INSERT_INITIAL = (byte) 0x00; // init the flag
665 static final byte INSERT_DEFAULT = (byte) 0x01; // default flag
666 static final byte INSERT_UNDO_WITH_PURGE = (byte) 0x02; // purge row on undo
667 static final byte INSERT_CONDITIONAL = (byte) 0x04; // conditional
668 // insert
669 static final byte INSERT_OVERFLOW = (byte) 0x08; // insert with
670 // possible overflow
671 static final byte INSERT_FOR_SPLIT = (byte) 0x10; // rawstore only
672
673
674 /**
675 * Fetch a record located in the passed in slot.
676 * <p>
677 * Fetch a record located in the passed in slot and fill-in the passed in
678 * StorebleRow and the Object columns contained within. If row
679 * is null then the record is locked but is not fetched.
680 * <BR>
681 * This interface allows the caller to either return a deleted row or not.
682 * If "ignoreDelete" is set to true, fetch the record regardless of whether
683 * it is deleted or not (same as above fetchFromSlot). However, if
684 * "ignoreDelete" is set to false and the and the slot correspond to a
685 * deleted row, null is returned.
686 * <BR>
687 * If a non-null Qualifier list is provided then the qualifier array will
688 * be applied to the row and the row will only be returned if the row
689 * qualifies, otherwise null will be returned. Values in the columns of
690 * row may or may not be altered while trying to apply the qualifiers, if
691 * null is returned the state of the columns is undefined. If a null
692 * Qualifier list is provided then no qualification is applied.
693 * <BR>
694 * If a non-null record handle is passed in, it is assumed that the record
695 * handle corresponds to the record in the slot. If record handle is null,
696 * a record handle will be manufactured and returned if the record is not
697 * deleted or if "ignoreDelete" is true. This parameter is here for the
698 * case where the caller have already manufactured the record handle for
699 * locking or other purposes so it would make sense for the page to avoid
700 * creating a new record handle object if possible.
701 *
702 *
703 * @param rh the record handle of the row. If non-null it must
704 * refer to the same record as the slot.
705 * @param slot the slot number
706 * @param row Row to be filled in with information from record.
707 * @param fetchDesc A structure to efficiently carry a set of parameters
708 * needed to describe the fetch, these include:
709 *
710 * validColumns - A bit map of which columns in the
711 * row to be fetched. ValidColumns will not be
712 * changed by RawStore.
713 *
714 * qualifier_list -
715 * A list of Qualifiers to apply to the row to see if
716 * the row should be returned.
717 *
718 * An array of qualifiers which restrict whether or not
719 * the row should be returned by the fetch. Rows for
720 * which any one of the qualifiers returns false are
721 * not returned by the fetch. If null, no qualification
722 * is done and the requested columns of the rows are
723 * returned. Qualifiers can only reference columns
724 * which are included in the scanColumnList. The
725 * column id that a qualifier returns is the column id
726 * the table, not the column id in the partial row
727 * being returned.
728 * qualifier_scratch_space -
729 * An array of int's that matches the size of the
730 * row[] array. Used to process qualifiers, if no
731 * qualifiers are input then array need not be
732 * input. Passed in rather than allocated so that
733 * space can be allocated a single time in a scan.
734 * If not passed in then raw store will allocate and
735 * deallocate per call.
736 *
737 * @param ignoreDelete if true, return row regardless of whether it is
738 * deleted or not. If false, only return non-deleted
739 * row.
740 *
741 * @return A handle to the record.
742 *
743 * @exception StandardException Standard Cloudscape error policy
744 *
745 * @see LockingPolicy
746 **/
747 public RecordHandle fetchFromSlot(
748 RecordHandle rh,
749 int slot,
750 Object[] row,
751 FetchDescriptor fetchDesc,
752 boolean ignoreDelete)
753 throws StandardException;
754
755
756 /**
757 Fetch a single field from a deleted or non-deleted record.
758 Fills in the passed in Object column with the field
759 identified by fieldid if column is not null, otherwise the record
760 is locked but not fetched.
761 <BR>
762 The fieldId of the first field is 0.
763 If the fieldId is >= the number of fields on the record,
764 column is restored to null
765 <P>
766 <B>Locking Policy</B>
767 <BR>
768 No locks are obtained.
769 It is up to the caller to obtain the correct locks.
770 <BR>
771
772 It is guaranteed that the page latch is not released by this method
773
774 @param slot is the slot number
775 @param fieldId is the column id
776 @param column is to be filled in with information from the record.
777
778 @return the Handle to the record that is locked
779
780 @exception StandardException Standard Cloudscape error policy, a
781 statement level exception is thrown if
782 the slot is not on the page.
783
784 @see Page#fetchFromSlot
785 @see LockingPolicy
786 */
787 public RecordHandle fetchFieldFromSlot(
788 int slot,
789 int fieldId,
790 Object column)
791 throws StandardException;
792
793 /**
794 * Test if a record is deleted.
795 * <p>
796 *
797 * <P>
798 * <B>Locking Policy</B>
799 * <BR>
800 * No locks are obtained.
801 *
802 * <BR>
803 * It is guaranteed that the page latch is not released by this method
804 *
805 * @param slot slot of record to be tested.
806 *
807 * @exception StandardException Standard Cloudscape error policy, a
808 * statement level exception is thrown if the
809 * slot is not on the page.
810 **/
811 public boolean isDeletedAtSlot(int slot)
812 throws StandardException;
813
814 /**
815 Update a field within the record, replacing its current value with
816 the stored representation of newValue. Record is identified by slot.
817 If the field does not exist then it is added to the record, but only if
818 (fieldId - 1) exists.
819
820 <BR><B>RESOLVE</B> right now it throws an exception if fieldId is not
821 already on the record, not add the next one as advertised.
822
823 <P>
824 <B>Locking Policy</B>
825 <P>
826 Calls the lockRecordForWrite() method of the LockingPolicy object
827 passed to the openContainer() call before the record is updated.
828
829 <BR>
830 It is guaranteed that the page latch is not released by this method
831
832
833 @param slot is the slot number
834 @param fieldId is the column id
835 @param newValue has the new colum value to be stored in the record
836 @param undo if logical undo may be necessary, a function pointer to the
837 access code where the logical undo logic resides. Null if logical undo
838 is not necessary.
839
840 @return a Handle to the updated record.
841
842 @exception StandardException Standard Cloudscape error policy, a
843 statement level exception is thrown if
844 the slot is not on the page, or if the
845 record is deleted, or if the fieldId
846 is not on the record and (fieldId - 1)
847 does not exist.
848
849 @exception StandardException
850 The container was not opened in update mode.
851
852 @see LockingPolicy
853 @see LogicalUndo
854 @see LogicalUndoable
855
856 */
857 public RecordHandle updateFieldAtSlot(
858 int slot,
859 int fieldId,
860 Object newValue,
861 LogicalUndo undo)
862 throws StandardException;
863
864
865 /**
866 * Fetch the number of fields in a record.
867 * <p>
868 *
869 * <P>
870 * <B>Locking Policy</B>
871 * <P>
872 * No locks are obtained.
873 *
874 * <BR>
875 * It is guaranteed that the page latch is not released by this method
876 *
877 * @param slot is the slot number
878 *
879 * @return the number of fields in the record
880 *
881 * @exception StandardException Standard Cloudscape error policy
882 **/
883 public int fetchNumFieldsAtSlot(int slot)
884 throws StandardException;
885
886 /**
887 Mark the record identified by slot as deleted or undeleted according to the
888 delete flag.
889
890
891 */
892 /**
893 * Mark the record at slot as deleted or undeleted according to delete flag.
894 * <p>
895 *
896 * <P>
897 * <B>Locking Policy</B>
898 * <P>
899 * Calls the lockRecordForWrite() method of the LockingPolicy object passed
900 * to the openContainer() call before the record is deleted. If record
901 * already deleted, and an attempt is made to delete it, an exception is
902 * thrown. If record not deleted, and an attempt is made to undelete it,
903 * an exception is thrown.
904 *
905 * <BR>
906 * MT - latched
907 *
908 * @return a Handle to the deleted/undeleted record.
909 *
910 * @param slot is the slot number
911 * @param delete true if this record is to be deleted false if this
912 * deleted record is to be marked undeleted
913 * @param undo if logical undo may be necessary, a function pointer to
914 * the access code where the logical undo logic resides.
915 * Null if logical undo is not necessary.
916 *
917 * @exception StandardException Standard Cloudscape error policy
918 * @exception StandardException The container was not opened in update mode.
919 * @exception StandardException A statement level exception is thrown when
920 * trying to delete an already deleted record,
921 * or undelete a not deleted record.
922 *
923 * @exception StandardException A statement level exception is thrown if
924 * the slot is not on the page.
925 *
926 * @see LockingPolicy
927 * @see Page#delete
928 * @see LogicalUndo
929 * @see LogicalUndoable
930 *
931 **/
932 public RecordHandle deleteAtSlot(
933 int slot,
934 boolean delete,
935 LogicalUndo undo)
936 throws StandardException;
937
938
939 /**
940 * Purge the row(s) from page.
941 * <p>
942 * Purge the row(s) from page, get rid of the row(s) and slot(s) -
943 * <B>USE WITH CAUTION</B>,
944 * please see entire description of this operation before attempting to
945 * use this.
946 *
947 * Starting from the specified slot, n rows will be purged. That is, rows
948 * that occupies from slot to slot+n-1 will be purged from the page.
949 *
950 * <P>
951 * <B>Locking Policy</B>
952 * <P>
953 * Calls the lockRecordForWrite() method of the LockingPolicy object passed
954 * to the openContainer() call before the records are purged.
955 * <P>
956 *
957 * <B>NOTE : CAVEAT</B><BR>
958 * This operation will physically get rid of the row from the page, so if a
959 * subsequent operation on this page uses a slot that has been purged, then
960 * the undo of this operation will fail. It is only safe to use this
961 * operation if the caller knows that it has exclusive access to the page
962 * for the duration of the transaction, i.e, effectively holding a page
963 * lock on the page
964 * <P>
965 * <B>NOTE</B><BR>
966 * Outstanding handles to purged rows are no longer valid, accessing them
967 * will cause an exception to be thrown.
968 *
969 * <BR>
970 *<B>NOTE : Data Logging for Purges</B><BR>
971 * needDataLogged is used to specify whether data is required to be
972 * logged for purge operatios. Data Logging is required
973 * Only if the row can be reused or required for key search if a purge is
974 * rolled back;(rollback can occur if the system crashes in the middle of
975 * purges or some unexpected error condiditions rolled back.
976 * For example:
977 * 1)Btree expects the data to be there if a purge is rolled back;
978 * needDataLogged=true
979 * 2)Heaps does not care if data exist because only operation that can occur
980 * on a row whose purge rolled back is purging again.(needDataLogged=false)
981 *
982 * MT - latched
983 *
984 *
985 * @param slot the starting slot number
986 * @param numpurges number of slots to purge. If <= 0,
987 * just returns as a no-op.
988 * @param needDataLogged if set to true data is logged for purges else
989 * only headers.
990 *
991 * @exception StandardException Standard Cloudscape error policy
992 * @see LockingPolicy
993 **/
994 public void purgeAtSlot(
995 int slot,
996 int numpurges,
997 boolean needDataLogged)
998 throws StandardException;
999
1000
1001 /**
1002 * move rows from one page to another, purging in the process.
1003 * <p>
1004 *
1005 * Move from this page slot[src_slot] to slot[src_slot+num_rows-1] to
1006 * destPage slot[dest_slot] to slot[dest_slot + num_rows - 1], in that
1007 * order. Both this page and destPage must be latched and from the same
1008 * container with the same page and record format.
1009 *
1010 * <BR>Slot[src_slot] to slot[src_slot+numrows-1] will be purged from this
1011 * page. RecordId on the dest page will be brand new and not in any
1012 * particular order or range. RecordId of the purged rows in this page is
1013 * never reused. Deleted and undeleted rows are copied over just the same.
1014 *
1015 * Exception will be thrown if this page does not have all the rows in the
1016 * moved over range.
1017 *
1018 * <BR><B>RESOLVE: reserve space now not copied over because in btree, a
1019 * row never shrinks. When this routine is called by heap or by some page
1020 * which will have shrunken row, then we need to add that </B>
1021 *
1022 * <BR>DestPage must have at least dest_slot row occupying slot[0] to
1023 * slot[dest_slot-1]. DestPage must have enough space to take the copied
1024 * over data. Rows that occupied slot number > dest_slot will be moved up
1025 * the slot (I.e., slot[dest_slot] -> slot[dest_slot + num_rows]).
1026 *
1027 * <BR>If this operation rolls back, this page (the src page) will get the
1028 * rows back and the dest page will purge the rows that were copied - this
1029 * is as if the rows were inserted into the dest page with
1030 * INSERT_UNDO_WITH_PURGE.
1031 *
1032 * <P>
1033 * <B>Locking Policy</B>
1034 * <P>
1035 * Calls the lockRecordForWrite() method of the LockingPolicy object
1036 * passed to the openContainer() call before the rows are copied over and
1037 * bore the records are purged. I.e, for num_rows moved, there will be
1038 * 2*num_rows calls to lockRecordForWrite.
1039 * <P>
1040 *
1041 * <P><B>Use with caution</B>
1042 * <BR>As with a normal purge, no space is reserved on this page for
1043 * rollback of the purge, so you must commit before inserting any rows
1044 * onto this page - unless those inserts are INSERT_UNDO_WITH_PURGE.
1045 *
1046 * @param destPage the page to copy to
1047 * @param src_slot start copying from this slot
1048 * @param num_rows copy and purge this many rows from this page
1049 * @param dest_slot copying into this slot of destPage
1050 *
1051 * @exception StandardException Standard Cloudscape error policy
1052 **/
1053 public void copyAndPurge(
1054 Page destPage,
1055 int src_slot,
1056 int num_rows,
1057 int dest_slot)
1058 throws StandardException;
1059
1060 /**
1061 Update the complete record identified by the slot.
1062
1063 <P>
1064 <B>Locking Policy</B>
1065 <P>
1066 Calls the lockRecordForWrite() method of the LockingPolicy object
1067 passed to the openContainer() call before the record is undeleted.
1068 If record already deleted, an exception is thrown.
1069
1070 <BR>
1071 It is guaranteed that the page latch is not released by this method
1072
1073 @return a Handle to the updated record.
1074 @param slot is the slot number
1075 @param validColumns a bit map of which columns in the row is valid.
1076 ValidColumns will not be changed by RawStore.
1077
1078 @exception StandardException Standard Cloudscape error policy
1079 @exception StandardException The container was not opened in update mode.
1080 @exception StandardException if the slot is not on the page.
1081
1082 @see Page#update
1083 */
1084 RecordHandle updateAtSlot(
1085 int slot,
1086 Object[] row,
1087 FormatableBitSet validColumns)
1088 throws StandardException;
1089
1090 /*
1091 Page operations
1092 */
1093
1094 /**
1095 Unlatch me, the page is exclusivly latched by its current user until
1096 this method call is made.
1097 <BR>
1098 After using this method the caller must throw away the
1099 reference to the Page object, e.g.
1100 <PRE>
1101 ref.unlatch();
1102 ref = null;
1103 </PRE>
1104 <BR>
1105 The page will be released automatically at the close of the
1106 container if this method is not called explictly.
1107
1108 <BR>
1109 MT - latched
1110
1111 */
1112 public void unlatch();
1113
1114
1115
1116 /**
1117 Return the number of records on the page. The returned count includes rows that are deleted,
1118 i.e. it is the same as the number of slots on the page.
1119
1120 <BR>
1121 MT - latched
1122
1123 @exception StandardException Standard Cloudscape error policy
1124 */
1125
1126 public int recordCount() throws StandardException;
1127
1128 /**
1129 Return the number of records on this page that are <B> not </B> marked as deleted.
1130
1131 <BR>
1132 MT - latched
1133
1134 @exception StandardException Standard Cloudscape error policy
1135 */
1136
1137 public int nonDeletedRecordCount() throws StandardException;
1138
1139 /**
1140 Set the aux object for this page.
1141 To clear the auxObject in the page, pass in a null AuxObject.
1142 If the AuxObject has already been set, this method will
1143 call auxObjectInvalidated() on the old aux objkect and replace it with aux.
1144
1145 <BR>
1146 MT - latched
1147
1148 @see AuxObject
1149 **/
1150 public void setAuxObject(AuxObject aux);
1151
1152 /**
1153 Retrieve this page's aux object, returning null if there isn't one. The reference returned
1154 must only be used while the page is latched, once unlatch is called the reference to the
1155 aux object must be discarded.
1156
1157 <BR> MT - latched
1158
1159 @see AuxObject
1160 **/
1161 public AuxObject getAuxObject();
1162
1163 /**
1164 Returns true if the page is latched. Only intended to be used as a Sanity check. Callers must
1165 discard Page references once unlatch is called.
1166
1167 <BR>
1168 MT - latched
1169 */
1170
1171
1172 /*
1173 * time stamp - for those implmentation that supports it
1174 */
1175
1176 /**
1177 Set the time stamp to what is on page at this instance. No op if this
1178 page does not support time stamp.
1179
1180 @exception StandardException Standard Cloudscape error policy.
1181 */
1182 void setTimeStamp(PageTimeStamp ts) throws StandardException;
1183
1184
1185 /**
1186 Return a time stamp that can be used to identify the page of this
1187 specific instance. For pages that don't support timestamp, returns
1188 null.
1189 */
1190 PageTimeStamp currentTimeStamp();
1191
1192 /**
1193 See if timeStamp for this page is the same as the current
1194 instance of the page. Null timeStamp never equals the instance of the
1195 page.
1196
1197 @param ts the time stamp gotten from an earlier call to this page's
1198 getTimeStamp
1199 @return true if timestamp is the same
1200 @exception StandardException Standard Cloudscape error policy.
1201
1202 @see PageTimeStamp
1203 */
1204 boolean equalTimeStamp(PageTimeStamp ts) throws StandardException;
1205
1206 public boolean isLatched();
1207
1208 public static final String DIAG_PAGE_SIZE = "pageSize";
1209 public static final String DIAG_RESERVED_SPACE = "reserveSpace";
1210 public static final String DIAG_MINIMUM_REC_SIZE = "minRecSize";
1211 public static final String DIAG_BYTES_FREE = "bytesFree";
1212 public static final String DIAG_BYTES_RESERVED = "bytesReserved";
1213 public static final String DIAG_NUMOVERFLOWED = "numOverFlowed";
1214 public static final String DIAG_ROWSIZE = "rowSize";
1215 public static final String DIAG_MINROWSIZE = "minRowSize";
1216 public static final String DIAG_MAXROWSIZE = "maxRowSize";
1217 public static final String DIAG_PAGEOVERHEAD = "pageOverhead";
1218 public static final String DIAG_SLOTTABLE_SIZE = "slotTableSize";
1219}