2 Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; version 2 of the License.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 /* Read and write key blocks */
20 #include "myisamdef.h"
22 /* Fetch a key-page in memory */
24 uchar
*_mi_fetch_keypage(register MI_INFO
*info
, MI_KEYDEF
*keyinfo
,
25 my_off_t page
, int level
,
26 uchar
*buff
, int return_buffer
)
30 DBUG_ENTER("_mi_fetch_keypage");
31 DBUG_PRINT("enter",("page: %ld", (long) page
));
33 tmp
=(uchar
*) key_cache_read(info
->s
->key_cache
,
34 info
->s
->kfile
, page
, level
, (uchar
*) buff
,
35 (uint
) keyinfo
->block_length
,
36 (uint
) keyinfo
->block_length
,
38 if (tmp
== info
->buff
)
42 DBUG_PRINT("error",("Got errno: %d from key_cache_read",my_errno
));
43 info
->last_keypage
=HA_OFFSET_ERROR
;
44 mi_print_error(info
->s
, HA_ERR_CRASHED
);
45 my_errno
=HA_ERR_CRASHED
;
48 info
->last_keypage
=page
;
49 page_size
=mi_getint(tmp
);
50 if (page_size
< 4 || page_size
> keyinfo
->block_length
)
52 DBUG_PRINT("error",("page %lu had wrong page length: %u",
53 (ulong
) page
, page_size
));
54 DBUG_DUMP("page", tmp
, keyinfo
->block_length
);
55 info
->last_keypage
= HA_OFFSET_ERROR
;
56 mi_print_error(info
->s
, HA_ERR_CRASHED
);
57 my_errno
= HA_ERR_CRASHED
;
61 } /* _mi_fetch_keypage */
64 /* Write a key-page on disk */
66 int _mi_write_keypage(register MI_INFO
*info
, register MI_KEYDEF
*keyinfo
,
67 my_off_t page
, int level
, uchar
*buff
)
70 DBUG_ENTER("_mi_write_keypage");
72 #ifndef FAST /* Safety check */
73 if (page
< info
->s
->base
.keystart
||
74 page
+keyinfo
->block_length
> info
->state
->key_file_length
||
75 (page
& (MI_MIN_KEY_BLOCK_LENGTH
-1)))
77 DBUG_PRINT("error",("Trying to write inside key status region: key_start: %lu length: %lu page: %lu",
78 (long) info
->s
->base
.keystart
,
79 (long) info
->state
->key_file_length
,
84 DBUG_PRINT("page",("write page at: %lu",(long) page
));
85 DBUG_DUMP("buff",(uchar
*) buff
,mi_getint(buff
));
88 if ((length
=keyinfo
->block_length
) > IO_SIZE
*2 &&
89 info
->state
->key_file_length
!= page
+length
)
90 length
= ((mi_getint(buff
)+IO_SIZE
-1) & (uint
) ~(IO_SIZE
-1));
91 DBUG_RETURN((key_cache_write(info
->s
->key_cache
,
92 info
->s
->kfile
,page
, level
, (uchar
*) buff
,length
,
93 (uint
) keyinfo
->block_length
,
94 (int) ((info
->lock_type
!= F_UNLCK
) ||
95 info
->s
->delay_key_write
))));
96 } /* mi_write_keypage */
99 /* Remove page from disk */
101 int _mi_dispose(register MI_INFO
*info
, MI_KEYDEF
*keyinfo
, my_off_t pos
,
106 DBUG_ENTER("_mi_dispose");
107 DBUG_PRINT("enter",("pos: %ld", (long) pos
));
109 old_link
= info
->s
->state
.key_del
[keyinfo
->block_size_index
];
110 info
->s
->state
.key_del
[keyinfo
->block_size_index
]= pos
;
111 mi_sizestore(buff
,old_link
);
112 info
->s
->state
.changed
|= STATE_NOT_SORTED_PAGES
;
113 DBUG_RETURN(key_cache_write(info
->s
->key_cache
,
114 info
->s
->kfile
, pos
, level
, buff
,
116 (uint
) keyinfo
->block_length
,
117 (int) (info
->lock_type
!= F_UNLCK
)));
121 /* Make new page on disk */
123 my_off_t
_mi_new(register MI_INFO
*info
, MI_KEYDEF
*keyinfo
, int level
)
127 DBUG_ENTER("_mi_new");
129 if ((pos
= info
->s
->state
.key_del
[keyinfo
->block_size_index
]) ==
132 if (info
->state
->key_file_length
>=
133 info
->s
->base
.max_key_file_length
- keyinfo
->block_length
)
135 my_errno
=HA_ERR_INDEX_FILE_FULL
;
136 DBUG_RETURN(HA_OFFSET_ERROR
);
138 pos
=info
->state
->key_file_length
;
139 info
->state
->key_file_length
+= keyinfo
->block_length
;
143 if (!key_cache_read(info
->s
->key_cache
,
144 info
->s
->kfile
, pos
, level
,
147 (uint
) keyinfo
->block_length
,0))
148 pos
= HA_OFFSET_ERROR
;
150 info
->s
->state
.key_del
[keyinfo
->block_size_index
]= mi_sizekorr(buff
);
152 info
->s
->state
.changed
|= STATE_NOT_SORTED_PAGES
;
153 DBUG_PRINT("exit",("Pos: %ld",(long) pos
));