1 : /* Copyright (C) 2006 MySQL AB & Ramil Kalimullin
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 : #include "maria_def.h"
17 : #include "trnman.h"
18 : #include "ma_key_recover.h"
19 :
20 : #ifdef HAVE_RTREE_KEYS
21 : #include "ma_rt_index.h"
22 : #include "ma_rt_key.h"
23 : #include "ma_rt_mbr.h"
24 :
25 : /*
26 : Add key to the page
27 :
28 : RESULT VALUES
29 : -1 Error
30 : 0 Not split
31 : 1 Split
32 : */
33 :
34 : int maria_rtree_add_key(const MARIA_KEY *key, MARIA_PAGE *page,
35 : my_off_t *new_page)
36 0 : {
37 0 : MARIA_HA *info= page->info;
38 0 : MARIA_SHARE *share= info->s;
39 0 : uint page_size= page->size;
40 0 : uint nod_flag= page->node;
41 0 : uchar *key_pos= rt_PAGE_END(page);
42 0 : uint tot_key_length= key->data_length + key->ref_length + nod_flag;
43 0 : DBUG_ENTER("maria_rtree_add_key");
44 :
45 0 : if (page_size + tot_key_length <=
46 : (uint)(key->keyinfo->block_length - KEYPAGE_CHECKSUM_SIZE))
47 : {
48 : /* split won't be necessary */
49 0 : if (nod_flag)
50 : {
51 0 : DBUG_ASSERT(_ma_kpos(nod_flag, key->data) <
52 : info->state->key_file_length);
53 : /* We don't store reference to row on nod pages for rtree index */
54 0 : tot_key_length-= key->ref_length;
55 : }
56 : /* save key */
57 0 : memcpy(key_pos, key->data - nod_flag, tot_key_length);
58 0 : page->size+= tot_key_length;
59 0 : page_store_size(share, page);
60 0 : if (share->now_transactional &&
61 : _ma_log_add(page, key_pos - page->buff,
62 : key_pos, tot_key_length, tot_key_length, 0))
63 0 : DBUG_RETURN(-1);
64 0 : DBUG_RETURN(0);
65 : }
66 0 : DBUG_RETURN(maria_rtree_split_page(key, page, new_page) ? -1 : 1);
67 : }
68 :
69 :
70 : /*
71 : Delete key from the page
72 :
73 : Notes
74 : key_length is only the data part of the key
75 : */
76 :
77 : int maria_rtree_delete_key(MARIA_PAGE *page, uchar *key, uint key_length)
78 0 : {
79 0 : MARIA_HA *info= page->info;
80 0 : MARIA_SHARE *share= info->s;
81 : uint key_length_with_nod_flag;
82 : uchar *key_start;
83 :
84 0 : key_start= key - page->node;
85 0 : if (!page->node)
86 0 : key_length+= share->base.rec_reflength;
87 :
88 0 : memmove(key_start, key + key_length, page->size - key_length -
89 : (key - page->buff));
90 0 : key_length_with_nod_flag= key_length + page->node;
91 0 : page->size-= key_length_with_nod_flag;
92 0 : page_store_size(share, page);
93 0 : if (share->now_transactional &&
94 : _ma_log_delete(page, key_start, 0, key_length_with_nod_flag))
95 0 : return -1;
96 0 : return 0;
97 : }
98 :
99 :
100 : /*
101 : Calculate and store key MBR into *key.
102 : */
103 :
104 : int maria_rtree_set_key_mbr(MARIA_HA *info, MARIA_KEY *key,
105 : my_off_t child_page)
106 0 : {
107 : MARIA_PAGE page;
108 0 : DBUG_ENTER("maria_rtree_set_key_mbr");
109 0 : if (_ma_fetch_keypage(&page, info, key->keyinfo, child_page,
110 : PAGECACHE_LOCK_LEFT_UNLOCKED,
111 : DFLT_INIT_HITS, info->buff, 0))
112 0 : DBUG_RETURN(-1);
113 :
114 0 : DBUG_RETURN(maria_rtree_page_mbr(key->keyinfo->seg,
115 : &page, key->data, key->data_length));
116 : }
117 :
118 : #endif /*HAVE_RTREE_KEYS*/
|