~drizzle-trunk/drizzle/development

1 by brian
clean slate
1
/* Copyright (C) 2000-2002, 2004-200 MySQL AB
2
3
   This program is free software; you can redistribute it and/or modify
4
   it under the terms of the GNU General Public License as published by
5
   the Free Software Foundation; version 2 of the License.
6
7
   This program is distributed in the hope that it will be useful,
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
   GNU General Public License for more details.
11
12
   You should have received a copy of the GNU General Public License
13
   along with this program; if not, write to the Free Software
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
16
/* remove current record in heap-database */
17
18
#include "heapdef.h"
19
481 by Brian Aker
Remove all of uchar.
20
int heap_delete(HP_INFO *info, const unsigned char *record)
1 by brian
clean slate
21
{
481 by Brian Aker
Remove all of uchar.
22
  unsigned char *pos;
1 by brian
clean slate
23
  HP_SHARE *share=info->s;
24
  HP_KEYDEF *keydef, *end, *p_lastinx;
482 by Brian Aker
Remove uint.
25
  uint32_t rec_length, chunk_count;
1 by brian
clean slate
26
27
  test_active(info);
28
51.3.4 by Jay Pipes
Final removal from heap storage engine plus fixes from MontyT re: _mi_report_crashed()
29
  if (info->opt_flag & READ_CHECK_USED)
51.3.1 by Jay Pipes
Removed all DBUG symbols from heap storage engine
30
    return(my_errno);			/* Record changed */
1 by brian
clean slate
31
  share->changed=1;
32
244.1.1 by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns.
33
  rec_length = hp_get_encoded_data_length(share, record, &chunk_count);
34
1 by brian
clean slate
35
  if ( --(share->records) < share->blength >> 1) share->blength>>=1;
36
  pos=info->current_ptr;
37
38
  p_lastinx = share->keydef + info->lastinx;
39
  for (keydef = share->keydef, end = keydef + share->keys; keydef < end; 
40
       keydef++)
41
  {
42
    if ((*keydef->delete_key)(info, keydef, record, pos, keydef == p_lastinx))
43
      goto err;
44
  }
45
46
  info->update=HA_STATE_DELETED;
244.1.1 by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns.
47
  hp_free_chunks(&share->recordspace, pos);
1 by brian
clean slate
48
  info->current_hash_ptr=0;
49
51.3.1 by Jay Pipes
Removed all DBUG symbols from heap storage engine
50
  return(0);
1 by brian
clean slate
51
err:
52
  if (++(share->records) == share->blength)
53
    share->blength+= share->blength;
51.3.1 by Jay Pipes
Removed all DBUG symbols from heap storage engine
54
  return(my_errno);
1 by brian
clean slate
55
}
56
57
58
/*
59
  Remove one key from rb-tree
60
*/
61
62
int hp_rb_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo,
481 by Brian Aker
Remove all of uchar.
63
		   const unsigned char *record, unsigned char *recpos, int flag)
1 by brian
clean slate
64
{
65
  heap_rb_param custom_arg;
482 by Brian Aker
Remove uint.
66
  uint32_t old_allocated;
1 by brian
clean slate
67
  int res;
68
69
  if (flag) 
70
    info->last_pos= NULL; /* For heap_rnext/heap_rprev */
71
72
  custom_arg.keyseg= keyinfo->seg;
73
  custom_arg.key_length= hp_rb_make_key(keyinfo, info->recbuf, record, recpos);
74
  custom_arg.search_flag= SEARCH_SAME;
75
  old_allocated= keyinfo->rb_tree.allocated;
76
  res= tree_delete(&keyinfo->rb_tree, info->recbuf, custom_arg.key_length,
77
                   &custom_arg);
78
  info->s->index_length-= (old_allocated - keyinfo->rb_tree.allocated);
79
  return res;
80
}
81
82
83
/*
84
  Remove one key from hash-table
85
86
  SYNPOSIS
87
    hp_delete_key()
88
    info		Hash handler
89
    keyinfo		key definition of key that we want to delete
90
    record		row data to be deleted
91
    recpos		Pointer to heap record in memory
92
    flag		Is set if we want's to correct info->current_ptr
93
94
  RETURN
95
    0      Ok
96
    other  Error code
97
*/
98
99
int hp_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo,
481 by Brian Aker
Remove all of uchar.
100
		  const unsigned char *record, unsigned char *recpos, int flag)
1 by brian
clean slate
101
{
291 by Brian Aker
Head ulong conversion.
102
  uint32_t blength,pos2,pos_hashnr,lastpos_hashnr;
1 by brian
clean slate
103
  HASH_INFO *lastpos,*gpos,*pos,*pos3,*empty,*last_ptr;
104
  HP_SHARE *share=info->s;
105
106
  blength=share->blength;
107
  if (share->records+1 == blength)
108
    blength+= blength;
244.1.1 by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns.
109
110
  /* find the very last HASH_INFO pointer in the index */
111
  /* note that records has already been decremented */
1 by brian
clean slate
112
  lastpos=hp_find_hash(&keyinfo->block,share->records);
113
  last_ptr=0;
114
115
  /* Search after record with key */
116
  pos= hp_find_hash(&keyinfo->block,
117
		    hp_mask(hp_rec_hashnr(keyinfo, record), blength,
118
			    share->records + 1));
119
  gpos = pos3 = 0;
120
121
  while (pos->ptr_to_rec != recpos)
122
  {
123
    if (flag && !hp_rec_key_cmp(keyinfo, record, pos->ptr_to_rec, 0))
124
      last_ptr=pos;				/* Previous same key */
125
    gpos=pos;
126
    if (!(pos=pos->next_key))
127
    {
51.3.1 by Jay Pipes
Removed all DBUG symbols from heap storage engine
128
      return(my_errno=HA_ERR_CRASHED);	/* This shouldn't happend */
1 by brian
clean slate
129
    }
130
  }
131
132
  /* Remove link to record */
133
134
  if (flag)
135
  {
136
    /* Save for heap_rnext/heap_rprev */
137
    info->current_hash_ptr=last_ptr;
138
    info->current_ptr = last_ptr ? last_ptr->ptr_to_rec : 0;
139
  }
140
  empty=pos;
244.1.1 by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns.
141
  if (gpos) {
142
    /* gpos says we have previous HASH_INFO, change previous to point to next, this way unlinking "empty" */
143
    gpos->next_key=pos->next_key;
144
  }
1 by brian
clean slate
145
  else if (pos->next_key)
146
  {
244.1.1 by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns.
147
    /* no previous gpos, this pos is the first in the list and it has pointer to "next" */
148
    /* move next HASH_INFO data to our pos, to free up space at the next position */
149
    /* remember next pos as "empty", nobody refers to "empty" at this point */
1 by brian
clean slate
150
    empty=pos->next_key;
151
    pos->ptr_to_rec=empty->ptr_to_rec;
152
    pos->next_key=empty->next_key;
153
  }
154
  else
244.1.1 by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns.
155
  {
156
    /* this was the only HASH_INFO at this position */
1 by brian
clean slate
157
    keyinfo->hash_buckets--;
244.1.1 by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns.
158
  }
1 by brian
clean slate
159
160
  if (empty == lastpos)			/* deleted last hash key */
51.3.1 by Jay Pipes
Removed all DBUG symbols from heap storage engine
161
    return (0);
1 by brian
clean slate
162
163
  /* Move the last key (lastpos) */
164
  lastpos_hashnr = hp_rec_hashnr(keyinfo, lastpos->ptr_to_rec);
165
  /* pos is where lastpos should be */
166
  pos=hp_find_hash(&keyinfo->block, hp_mask(lastpos_hashnr, share->blength,
167
					    share->records));
168
  if (pos == empty)			/* Move to empty position. */
169
  {
170
    empty[0]=lastpos[0];
51.3.1 by Jay Pipes
Removed all DBUG symbols from heap storage engine
171
    return(0);
1 by brian
clean slate
172
  }
173
  pos_hashnr = hp_rec_hashnr(keyinfo, pos->ptr_to_rec);
174
  /* pos3 is where the pos should be */
175
  pos3= hp_find_hash(&keyinfo->block,
176
		     hp_mask(pos_hashnr, share->blength, share->records));
177
  if (pos != pos3)
178
  {					/* pos is on wrong posit */
179
    empty[0]=pos[0];			/* Save it here */
180
    pos[0]=lastpos[0];			/* This shold be here */
181
    hp_movelink(pos, pos3, empty);	/* Fix link to pos */
51.3.1 by Jay Pipes
Removed all DBUG symbols from heap storage engine
182
    return(0);
1 by brian
clean slate
183
  }
184
  pos2= hp_mask(lastpos_hashnr, blength, share->records + 1);
185
  if (pos2 == hp_mask(pos_hashnr, blength, share->records + 1))
186
  {					/* Identical key-positions */
187
    if (pos2 != share->records)
188
    {
189
      empty[0]=lastpos[0];
190
      hp_movelink(lastpos, pos, empty);
51.3.1 by Jay Pipes
Removed all DBUG symbols from heap storage engine
191
      return(0);
1 by brian
clean slate
192
    }
193
    pos3= pos;				/* Link pos->next after lastpos */
194
  }
195
  else
196
  {
197
    pos3= 0;				/* Different positions merge */
198
    keyinfo->hash_buckets--;
199
  }
200
201
  empty[0]=lastpos[0];
202
  hp_movelink(pos3, empty, pos->next_key);
203
  pos->next_key=empty;
51.3.1 by Jay Pipes
Removed all DBUG symbols from heap storage engine
204
  return(0);
1 by brian
clean slate
205
}