1/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
15
16/* This file is included in all heap-files */
17
18#include <my_global.h>
19#include <my_base.h>
20C_MODE_START
21#include <my_pthread.h>
22#include "heap.h" /* Structs & some defines */
23#include "my_tree.h"
24
25/*
26 When allocating keys /rows in the internal block structure, do it
27 within the following boundaries.
28
29 The challenge is to find the balance between allocate as few blocks
30 as possible and keep memory consumption down.
31*/
32
33#define HP_MIN_RECORDS_IN_BLOCK 16
34#define HP_MAX_RECORDS_IN_BLOCK 8192
35
36 /* Some extern variables */
37
38extern LIST *heap_open_list,*heap_share_list;
39
40#define test_active(info) \
41if (!(info->update & HA_STATE_AKTIV))\
42{ my_errno=HA_ERR_NO_ACTIVE_RECORD; DBUG_RETURN(-1); }
43#define hp_find_hash(A,B) ((HASH_INFO*) hp_find_block((A),(B)))
44
45 /* Find pos for record and update it in info->current_ptr */
46#define hp_find_record(info,pos) (info)->current_ptr= hp_find_block(&(info)->s->block,pos)
47
48typedef struct st_hp_hash_info
49{
50 struct st_hp_hash_info *next_key;
51 uchar *ptr_to_rec;
52 ulong hash_of_key;
53} HASH_INFO;
54
55typedef struct {
56 HA_KEYSEG *keyseg;
57 uint key_length;
58 uint search_flag;
59} heap_rb_param;
60
61 /* Prototypes for intern functions */
62
63extern HP_SHARE *hp_find_named_heap(const char *name);
64extern int hp_rectest(HP_INFO *info,const uchar *old);
65extern uchar *hp_find_block(HP_BLOCK *info,ulong pos);
66extern int hp_get_new_block(HP_SHARE *info, HP_BLOCK *block,
67 size_t* alloc_length);
68extern void hp_free(HP_SHARE *info);
69extern uchar *hp_free_level(HP_BLOCK *block,uint level,HP_PTRS *pos,
70 uchar *last_pos);
71extern int hp_write_key(HP_INFO *info, HP_KEYDEF *keyinfo,
72 const uchar *record, uchar *recpos);
73extern int hp_rb_write_key(HP_INFO *info, HP_KEYDEF *keyinfo,
74 const uchar *record, uchar *recpos);
75extern int hp_rb_delete_key(HP_INFO *info,HP_KEYDEF *keyinfo,
76 const uchar *record,uchar *recpos,int flag);
77extern int hp_delete_key(HP_INFO *info,HP_KEYDEF *keyinfo,
78 const uchar *record,uchar *recpos,int flag);
79extern HASH_INFO *_heap_find_hash(HP_BLOCK *block,ulong pos);
80extern uchar *hp_search(HP_INFO *info,HP_KEYDEF *keyinfo,const uchar *key,
81 uint nextflag);
82extern uchar *hp_search_next(HP_INFO *info, HP_KEYDEF *keyinfo,
83 const uchar *key, HASH_INFO *pos);
84extern ulong hp_hashnr(HP_KEYDEF *keyinfo,const uchar *key);
85extern ulong hp_rec_hashnr(HP_KEYDEF *keyinfo,const uchar *rec);
86extern void hp_movelink(HASH_INFO *pos,HASH_INFO *next_link,
87 HASH_INFO *newlink);
88extern int hp_rec_key_cmp(HP_KEYDEF *keydef,const uchar *rec1,
89 const uchar *rec2);
90extern int hp_key_cmp(HP_KEYDEF *keydef,const uchar *rec,
91 const uchar *key);
92extern void hp_make_key(HP_KEYDEF *keydef,uchar *key,const uchar *rec);
93extern uint hp_rb_make_key(HP_KEYDEF *keydef, uchar *key,
94 const uchar *rec, uchar *recpos);
95extern uint hp_rb_key_length(HP_KEYDEF *keydef, const uchar *key);
96extern uint hp_rb_null_key_length(HP_KEYDEF *keydef, const uchar *key);
97extern uint hp_rb_var_key_length(HP_KEYDEF *keydef, const uchar *key);
98extern my_bool hp_if_null_in_key(HP_KEYDEF *keyinfo, const uchar *record);
99extern int hp_close(HP_INFO *info);
100extern void hp_clear(HP_SHARE *info);
101extern void hp_clear_keys(HP_SHARE *info);
102extern uint hp_rb_pack_key(HP_KEYDEF *keydef, uchar *key, const uchar *old,
103 key_part_map keypart_map);
104
105extern mysql_mutex_t THR_LOCK_heap;
106
107#ifdef HAVE_PSI_INTERFACE
108extern PSI_mutex_key hp_key_mutex_HP_SHARE_intern_lock;
109void init_heap_psi_keys();
110#endif /* HAVE_PSI_INTERFACE */
111
112C_MODE_END
113
114/*
115 Calculate position number for hash value.
116 SYNOPSIS
117 hp_mask()
118 hashnr Hash value
119 buffmax Value such that
120 2^(n-1) < maxlength <= 2^n = buffmax
121 maxlength
122
123 RETURN
124 Array index, in [0..maxlength)
125*/
126
127static inline ulong hp_mask(ulong hashnr, ulong buffmax, ulong maxlength)
128{
129 if ((hashnr & (buffmax-1)) < maxlength) return (hashnr & (buffmax-1));
130 return (hashnr & ((buffmax >> 1) -1));
131}
132