2 * See the file LICENSE for redistribution information.
4 * Copyright (c) 1996, 1997, 1998
5 * Sleepycat Software. All rights reserved.
8 #pragma ident "%Z%%M% %I% %E% SMI"
13 static const char sccsid
[] = "@(#)bt_curadj.c 10.69 (Sleepycat) 12/2/98";
16 #ifndef NO_SYSTEM_INCLUDES
17 #include <sys/types.h>
29 * Display the current cursor list.
31 * PUBLIC: int __bam_cprint __P((DB *));
41 for (dbc
= TAILQ_FIRST(&dbp
->active_queue
);
42 dbc
!= NULL
; dbc
= TAILQ_NEXT(dbc
, links
)) {
43 cp
= (CURSOR
*)dbc
->internal
;
45 "%#0x->%#0x: page: %lu index: %lu dpage %lu dindex: %lu recno: %lu",
46 (u_int
)dbc
, (u_int
)cp
, (u_long
)cp
->pgno
, (u_long
)cp
->indx
,
47 (u_long
)cp
->dpgno
, (u_long
)cp
->dindx
, (u_long
)cp
->recno
);
48 if (F_ISSET(cp
, C_DELETED
))
49 fprintf(stderr
, " (deleted)");
50 fprintf(stderr
, "\n");
52 DB_THREAD_UNLOCK(dbp
);
60 * Update the cursors when items are deleted and when already deleted
61 * items are overwritten. Return the number of relevant cursors found.
63 * PUBLIC: int __bam_ca_delete __P((DB *, db_pgno_t, u_int32_t, int));
66 __bam_ca_delete(dbp
, pgno
, indx
, delete)
74 int count
; /* !!!: Has to contain max number of cursors. */
76 /* Recno is responsible for its own adjustments. */
77 if (dbp
->type
== DB_RECNO
)
81 * Adjust the cursors. We don't have to review the cursors for any
82 * thread of control other than the current one, because we have the
83 * page write locked at this point, and any other thread of control
84 * had better be using a different locker ID, meaning only cursors in
85 * our thread of control can be on the page.
87 * It's possible for multiple cursors within the thread to have write
88 * locks on the same page, but, cursors within a thread must be single
89 * threaded, so all we're locking here is the cursor linked list.
92 for (count
= 0, dbc
= TAILQ_FIRST(&dbp
->active_queue
);
93 dbc
!= NULL
; dbc
= TAILQ_NEXT(dbc
, links
)) {
94 cp
= (CURSOR
*)dbc
->internal
;
96 if ((cp
->pgno
== pgno
&& cp
->indx
== indx
) ||
97 (cp
->dpgno
== pgno
&& cp
->dindx
== indx
)) {
101 F_CLR(cp
, C_DELETED
);
105 DB_THREAD_UNLOCK(dbp
);
112 * Adjust the cursors during a delete or insert.
114 * PUBLIC: void __bam_ca_di __P((DB *, db_pgno_t, u_int32_t, int));
117 __bam_ca_di(dbp
, pgno
, indx
, adjust
)
126 /* Recno is responsible for its own adjustments. */
127 if (dbp
->type
== DB_RECNO
)
131 * Adjust the cursors. See the comment in __bam_ca_delete().
134 for (dbc
= TAILQ_FIRST(&dbp
->active_queue
);
135 dbc
!= NULL
; dbc
= TAILQ_NEXT(dbc
, links
)) {
136 cp
= (CURSOR
*)dbc
->internal
;
137 if (cp
->pgno
== pgno
&& cp
->indx
>= indx
)
139 if (cp
->dpgno
== pgno
&& cp
->dindx
>= indx
)
142 DB_THREAD_UNLOCK(dbp
);
147 * Adjust the cursors when moving items from a leaf page to a duplicates
150 * PUBLIC: void __bam_ca_dup __P((DB *,
151 * PUBLIC: db_pgno_t, u_int32_t, u_int32_t, db_pgno_t, u_int32_t));
154 __bam_ca_dup(dbp
, fpgno
, first
, fi
, tpgno
, ti
)
156 db_pgno_t fpgno
, tpgno
;
157 u_int32_t first
, fi
, ti
;
162 /* Recno is responsible for its own adjustments. */
163 if (dbp
->type
== DB_RECNO
)
167 * Adjust the cursors. See the comment in __bam_ca_delete().
170 for (dbc
= TAILQ_FIRST(&dbp
->active_queue
);
171 dbc
!= NULL
; dbc
= TAILQ_NEXT(dbc
, links
)) {
172 cp
= (CURSOR
*)dbc
->internal
;
174 * Ignore matching entries that have already been moved,
175 * we move from the same location on the leaf page more
178 if (cp
->dpgno
== PGNO_INVALID
&&
179 cp
->pgno
== fpgno
&& cp
->indx
== fi
) {
185 DB_THREAD_UNLOCK(dbp
);
190 * Adjust the cursors when doing reverse splits.
192 * PUBLIC: void __bam_ca_rsplit __P((DB *, db_pgno_t, db_pgno_t));
195 __bam_ca_rsplit(dbp
, fpgno
, tpgno
)
197 db_pgno_t fpgno
, tpgno
;
202 /* Recno is responsible for its own adjustments. */
203 if (dbp
->type
== DB_RECNO
)
207 * Adjust the cursors. See the comment in __bam_ca_delete().
210 for (dbc
= TAILQ_FIRST(&dbp
->active_queue
);
211 dbc
!= NULL
; dbc
= TAILQ_NEXT(dbc
, links
)) {
212 cp
= (CURSOR
*)dbc
->internal
;
213 if (cp
->pgno
== fpgno
)
216 DB_THREAD_UNLOCK(dbp
);
221 * Adjust the cursors when splitting a page.
223 * PUBLIC: void __bam_ca_split __P((DB *,
224 * PUBLIC: db_pgno_t, db_pgno_t, db_pgno_t, u_int32_t, int));
227 __bam_ca_split(dbp
, ppgno
, lpgno
, rpgno
, split_indx
, cleft
)
229 db_pgno_t ppgno
, lpgno
, rpgno
;
230 u_int32_t split_indx
;
236 /* Recno is responsible for its own adjustments. */
237 if (dbp
->type
== DB_RECNO
)
241 * Adjust the cursors. See the comment in __bam_ca_delete().
243 * If splitting the page that a cursor was on, the cursor has to be
244 * adjusted to point to the same record as before the split. Most
245 * of the time we don't adjust pointers to the left page, because
246 * we're going to copy its contents back over the original page. If
247 * the cursor is on the right page, it is decremented by the number of
248 * records split to the left page.
251 for (dbc
= TAILQ_FIRST(&dbp
->active_queue
);
252 dbc
!= NULL
; dbc
= TAILQ_NEXT(dbc
, links
)) {
253 cp
= (CURSOR
*)dbc
->internal
;
254 if (cp
->pgno
== ppgno
)
255 if (cp
->indx
< split_indx
) {
260 cp
->indx
-= split_indx
;
262 if (cp
->dpgno
== ppgno
)
263 if (cp
->dindx
< split_indx
) {
268 cp
->dindx
-= split_indx
;
271 DB_THREAD_UNLOCK(dbp
);