2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 /*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
24 /*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
25 /*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
26 /*%% (c) Copyright 1993, 1994 Novell, Inc. */
27 /*%% $XConsortium: ischange1key.c /main/3 1995/10/23 11:36:41 rswiston $ */
29 static char sccsid[] = "@(#)ischange1key.c 1.3 89/07/17 Copyr 1988 Sun Micro";
32 * Copyright (c) 1988 by Sun Microsystems, Inc.
39 * Update an index if necessary.
44 #include "isam_impl.h"
46 extern long *ismaxlong;
49 _change1key(fcb, pkeydesc2, record, oldrecord, recnum, newkey)
57 char keybuf1[MAXKEYSIZE];
58 char keybuf2[MAXKEYSIZE];
63 * Special case when there is no primary key.
65 if (pkeydesc2->k2_nparts == 0)
68 /* Get old key value. */
69 memset((char *)keybuf1, 0, pkeydesc2->k2_len);
70 _iskey_extract(pkeydesc2, oldrecord, keybuf1);
71 strecno(recnum, keybuf1);
73 /* Get new key value. */
74 memset((char *)keybuf2, 0, pkeydesc2->k2_len);
75 _iskey_extract(pkeydesc2, record, keybuf2);
76 strecno(recnum, keybuf2);
80 * See if the key changed.
82 if (memcmp(keybuf1, keybuf2, pkeydesc2->k2_len)) {
85 * Delete the old key entry from B tree.
87 btree = _isbtree_create(fcb, pkeydesc2);
88 _isbtree_search(btree, keybuf1);
90 if (ALLOWS_DUPS2(pkeydesc2)) {
93 * We must now scan all the duplicates till we found one with
94 * matching recno. We are positioned just before the first duplicate.
95 * Remember that the duplicates are ordered by their serial number.
97 * If too many duplicate entries exists, the performance will be
100 while ((pkey = _isbtree_next(btree)) != NULL) {
101 if (ldrecno(pkey + KEY_RECNO_OFF) == recnum)
102 break; /* We found the entry */
106 _isfatal_error("_del1key() cannot find entry in B tree");
108 _isbtree_remove(btree);
112 if ((pkey = _isbtree_current(btree)) == NULL ||
113 ldrecno(pkey + KEY_RECNO_OFF) != recnum)
114 _isfatal_error("_del1key() cannot find entry in B tree");
116 _isbtree_remove(btree);
118 _isbtree_destroy(btree);
121 * Insert new key entry into B tree.
124 btree = _isbtree_create(fcb, pkeydesc2);
126 if (ALLOWS_DUPS2(pkeydesc2)) {
129 * Duplicates allowed on this key.
130 * Try to read the last duplicate (with the highest serial number).
131 * If such duplicate exists, the inserted key entry will be
132 * assigned next higher value for duplicate serial number.
133 * If there is no such duplicate, assign duplicate serial number 1.
135 strecno(recnum, keybuf2 + KEY_RECNO_OFF);
136 memcpy( keybuf2 + KEY_DUPS_OFF,(char *)ismaxlong, LONGSIZE);
137 _isbtree_search(btree, keybuf2);
139 if ((pkey = _isbtree_current(btree)) != NULL &&
140 memcmp(pkey + RECNOSIZE + DUPIDSIZE,
141 keybuf2 + RECNOSIZE + DUPIDSIZE,
142 pkeydesc2->k2_len - RECNOSIZE - DUPIDSIZE) == 0) {
145 * A duplicate exists. Assign +1 value for the new serial
148 stlong(ldlong(pkey + KEY_DUPS_OFF) + 1, keybuf2 + KEY_DUPS_OFF);
151 * Indicate that there are allowed duplicate key values.
158 * This is the first duplicate. Assign serial number 1.
160 stlong(1L, keybuf2 + KEY_DUPS_OFF);
163 _isbtree_insert(btree, keybuf2);
164 _isbtree_destroy(btree);
171 /* Duplicates not allowed on this key.
172 * Set TID part to maximum value, causing the search path
173 * to point just past the possible duplicate in the key file
174 * If there is no duplicate, this is the correct spot to
175 * insert the new key entry.
178 memcpy( keybuf2 + KEY_RECNO_OFF,(char *)ismaxlong, LONGSIZE);
179 _isbtree_search (btree, keybuf2);
181 if ((pkey = _isbtree_current(btree)) != NULL &&
182 memcmp(pkey + RECNOSIZE, keybuf2 + RECNOSIZE,
183 pkeydesc2->k2_len - RECNOSIZE) == 0) {
184 _isbtree_destroy(btree);
188 strecno(recnum, keybuf2 + KEY_RECNO_OFF);
189 _isbtree_insert(btree, keybuf2);
190 _isbtree_destroy(btree);
195 * Return new key position.
198 memcpy( newkey,keybuf2, pkeydesc2->k2_len);