1 | /* Copyright (C) 2006 MySQL AB & MySQL Finland AB & TCX DataKonsult 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ |
15 | |
16 | /* Calculate a checksum for a row */ |
17 | |
18 | #include "maria_def.h" |
19 | |
20 | /** |
21 | Calculate a checksum for the record |
22 | |
23 | _ma_checksum() |
24 | @param info Maria handler |
25 | @param record Record |
26 | |
27 | @note |
28 | To ensure that the checksum is independent of the row format |
29 | we need to always calculate the checksum in the original field order. |
30 | |
31 | @return checksum |
32 | */ |
33 | |
34 | ha_checksum _ma_checksum(MARIA_HA *info, const uchar *record) |
35 | { |
36 | ha_checksum crc=0; |
37 | uint i,end; |
38 | MARIA_COLUMNDEF *base_column= info->s->columndef; |
39 | uint16 *column_nr= info->s->column_nr; |
40 | |
41 | if (info->s->base.null_bytes) |
42 | crc= my_checksum(crc, record, info->s->base.null_bytes); |
43 | |
44 | for (i= 0, end= info->s->base.fields ; i < end ; i++) |
45 | { |
46 | MARIA_COLUMNDEF *column= base_column + column_nr[i]; |
47 | const uchar *pos; |
48 | ulong length; |
49 | |
50 | if (record[column->null_pos] & column->null_bit) |
51 | continue; /* Null field */ |
52 | |
53 | pos= record + column->offset; |
54 | switch (column->type) { |
55 | case FIELD_BLOB: |
56 | { |
57 | uint blob_size_length= column->length- portable_sizeof_char_ptr; |
58 | length= _ma_calc_blob_length(blob_size_length, pos); |
59 | if (length) |
60 | { |
61 | memcpy((char**) &pos, pos + blob_size_length, sizeof(char*)); |
62 | crc= my_checksum(crc, pos, length); |
63 | } |
64 | continue; |
65 | } |
66 | case FIELD_VARCHAR: |
67 | { |
68 | uint pack_length= column->fill_length; |
69 | if (pack_length == 1) |
70 | length= (ulong) *pos; |
71 | else |
72 | length= uint2korr(pos); |
73 | pos+= pack_length; /* Skip length information */ |
74 | break; |
75 | } |
76 | default: |
77 | length= column->length; |
78 | break; |
79 | } |
80 | crc= my_checksum(crc, pos, length); |
81 | } |
82 | return crc; |
83 | } |
84 | |
85 | |
86 | ha_checksum _ma_static_checksum(MARIA_HA *info, const uchar *pos) |
87 | { |
88 | return my_checksum(0, pos, info->s->base.reclength); |
89 | } |
90 | |