1
by brian
clean slate |
1 |
/* Copyright (C) 2003 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 |
#include <sys/types.h> |
|
17 |
#include <sys/stat.h> |
|
18 |
#include <my_dir.h> |
|
19 |
#include "transparent_file.h" |
|
20 |
||
21 |
#define DEFAULT_CHAIN_LENGTH 512
|
|
22 |
/*
|
|
23 |
Version for file format.
|
|
24 |
1 - Initial Version. That is, the version when the metafile was introduced.
|
|
25 |
*/
|
|
26 |
||
27 |
#define TINA_VERSION 1
|
|
28 |
||
29 |
typedef struct st_tina_share { |
|
30 |
char *table_name; |
|
31 |
char data_file_name[FN_REFLEN]; |
|
32 |
uint table_name_length, use_count; |
|
33 |
/*
|
|
34 |
Below flag is needed to make log tables work with concurrent insert.
|
|
35 |
For more details see comment to ha_tina::update_status.
|
|
36 |
*/
|
|
37 |
my_bool is_log_table; |
|
38 |
/*
|
|
39 |
Here we save the length of the file for readers. This is updated by
|
|
40 |
inserts, updates and deletes. The var is initialized along with the
|
|
41 |
share initialization.
|
|
42 |
*/
|
|
43 |
off_t saved_data_file_length; |
|
44 |
pthread_mutex_t mutex; |
|
45 |
THR_LOCK lock; |
|
46 |
bool update_file_opened; |
|
47 |
bool tina_write_opened; |
|
48 |
File meta_file; /* Meta file we use */ |
|
49 |
File tina_write_filedes; /* File handler for readers */ |
|
50 |
bool crashed; /* Meta file is crashed */ |
|
51 |
ha_rows rows_recorded; /* Number of rows in tables */ |
|
52 |
uint data_file_version; /* Version of the data file used */ |
|
53 |
} TINA_SHARE; |
|
54 |
||
55 |
struct tina_set { |
|
56 |
off_t begin; |
|
57 |
off_t end; |
|
58 |
};
|
|
59 |
||
60 |
class ha_tina: public handler |
|
61 |
{
|
|
62 |
THR_LOCK_DATA lock; /* MySQL lock */ |
|
63 |
TINA_SHARE *share; /* Shared lock info */ |
|
64 |
off_t current_position; /* Current position in the file during a file scan */ |
|
65 |
off_t next_position; /* Next position in the file scan */ |
|
66 |
off_t local_saved_data_file_length; /* save position for reads */ |
|
67 |
off_t temp_file_length; |
|
68 |
uchar byte_buffer[IO_SIZE]; |
|
69 |
Transparent_file *file_buff; |
|
70 |
File data_file; /* File handler for readers */ |
|
71 |
File update_temp_file; |
|
72 |
String buffer; |
|
73 |
/*
|
|
74 |
The chain contains "holes" in the file, occured because of
|
|
75 |
deletes/updates. It is used in rnd_end() to get rid of them
|
|
76 |
in the end of the query.
|
|
77 |
*/
|
|
78 |
tina_set chain_buffer[DEFAULT_CHAIN_LENGTH]; |
|
79 |
tina_set *chain; |
|
80 |
tina_set *chain_ptr; |
|
81 |
uchar chain_alloced; |
|
82 |
uint32 chain_size; |
|
83 |
uint local_data_file_version; /* Saved version of the data file used */ |
|
84 |
bool records_is_known; |
|
85 |
MEM_ROOT blobroot; |
|
86 |
||
87 |
private: |
|
88 |
bool get_write_pos(off_t *end_pos, tina_set *closest_hole); |
|
89 |
int open_update_temp_file_if_needed(); |
|
90 |
int init_tina_writer(); |
|
91 |
int init_data_file(); |
|
92 |
||
93 |
public: |
|
94 |
ha_tina(handlerton *hton, TABLE_SHARE *table_arg); |
|
95 |
~ha_tina() |
|
96 |
{
|
|
97 |
if (chain_alloced) |
|
98 |
my_free(chain, 0); |
|
99 |
if (file_buff) |
|
100 |
delete file_buff; |
|
101 |
}
|
|
77.1.6
by Monty Taylor
CSV is clean. |
102 |
const char *table_type(void) const { return "CSV"; } |
103 |
const char *index_type(uint inx __attribute__((__unused__))) |
|
104 |
{ return "NONE"; } |
|
1
by brian
clean slate |
105 |
const char **bas_ext() const; |
106 |
uint64_t table_flags() const |
|
107 |
{
|
|
108 |
return (HA_NO_TRANSACTIONS | HA_REC_NOT_IN_SEQ | HA_NO_AUTO_INCREMENT | |
|
109 |
HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE); |
|
110 |
}
|
|
77.1.6
by Monty Taylor
CSV is clean. |
111 |
uint32_t index_flags(uint idx __attribute__((__unused__)), |
112 |
uint part __attribute__((__unused__)), |
|
113 |
bool all_parts __attribute__((__unused__))) const |
|
1
by brian
clean slate |
114 |
{
|
115 |
/*
|
|
116 |
We will never have indexes so this will never be called(AKA we return
|
|
117 |
zero)
|
|
118 |
*/
|
|
119 |
return 0; |
|
120 |
}
|
|
121 |
uint max_record_length() const { return HA_MAX_REC_LENGTH; } |
|
122 |
uint max_keys() const { return 0; } |
|
123 |
uint max_key_parts() const { return 0; } |
|
124 |
uint max_key_length() const { return 0; } |
|
125 |
/*
|
|
126 |
Called in test_quick_select to determine if indexes should be used.
|
|
127 |
*/
|
|
128 |
virtual double scan_time() { return (double) (stats.records+stats.deleted) / 20.0+10; } |
|
129 |
/* The next method will never be called */
|
|
130 |
virtual bool fast_key_read() { return 1;} |
|
131 |
/*
|
|
132 |
TODO: return actual upper bound of number of records in the table.
|
|
133 |
(e.g. save number of records seen on full table scan and/or use file size
|
|
134 |
as upper bound)
|
|
135 |
*/
|
|
136 |
ha_rows estimate_rows_upper_bound() { return HA_POS_ERROR; } |
|
137 |
||
138 |
int open(const char *name, int mode, uint open_options); |
|
139 |
int close(void); |
|
140 |
int write_row(uchar * buf); |
|
141 |
int update_row(const uchar * old_data, uchar * new_data); |
|
142 |
int delete_row(const uchar * buf); |
|
143 |
int rnd_init(bool scan=1); |
|
144 |
int rnd_next(uchar *buf); |
|
145 |
int rnd_pos(uchar * buf, uchar *pos); |
|
146 |
bool check_and_repair(THD *thd); |
|
147 |
int check(THD* thd, HA_CHECK_OPT* check_opt); |
|
148 |
bool is_crashed() const; |
|
149 |
int rnd_end(); |
|
150 |
int repair(THD* thd, HA_CHECK_OPT* check_opt); |
|
151 |
/* This is required for SQL layer to know that we support autorepair */
|
|
152 |
bool auto_repair() const { return 1; } |
|
153 |
void position(const uchar *record); |
|
154 |
int info(uint); |
|
155 |
int extra(enum ha_extra_function operation); |
|
156 |
int delete_all_rows(void); |
|
157 |
int create(const char *name, TABLE *form, HA_CREATE_INFO *create_info); |
|
158 |
bool check_if_incompatible_data(HA_CREATE_INFO *info, |
|
159 |
uint table_changes); |
|
160 |
||
161 |
THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to, |
|
162 |
enum thr_lock_type lock_type); |
|
163 |
||
164 |
/*
|
|
165 |
These functions used to get/update status of the handler.
|
|
166 |
Needed to enable concurrent inserts.
|
|
167 |
*/
|
|
168 |
void get_status(); |
|
169 |
void update_status(); |
|
170 |
||
171 |
/* The following methods were added just for TINA */
|
|
172 |
int encode_quote(uchar *buf); |
|
173 |
int find_current_row(uchar *buf); |
|
174 |
int chain_append(); |
|
175 |
};
|
|
176 |