~stewart/drizzle/embedded-innodb-create-select-transaction-arrgh

« back to all changes in this revision

Viewing changes to mysys/my_compress.c

  • Committer: brian
  • Date: 2008-06-25 05:29:13 UTC
  • Revision ID: brian@localhost.localdomain-20080625052913-6upwo0jsrl4lnapl
clean slate

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2000 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
/* Written by Sinisa Milivojevic <sinisa@mysql.com> */
 
17
 
 
18
#include <my_global.h>
 
19
#include <my_sys.h>
 
20
#include <m_string.h>
 
21
#include <zlib.h>
 
22
 
 
23
/*
 
24
   This replaces the packet with a compressed packet
 
25
 
 
26
   SYNOPSIS
 
27
     my_compress()
 
28
     packet     Data to compress. This is is replaced with the compressed data.
 
29
     len        Length of data to compress at 'packet'
 
30
     complen    out: 0 if packet was not compressed
 
31
 
 
32
   RETURN
 
33
     1   error. 'len' is not changed'
 
34
     0   ok.  In this case 'len' contains the size of the compressed packet
 
35
*/
 
36
 
 
37
my_bool my_compress(uchar *packet, size_t *len, size_t *complen)
 
38
{
 
39
  DBUG_ENTER("my_compress");
 
40
  if (*len < MIN_COMPRESS_LENGTH)
 
41
  {
 
42
    *complen=0;
 
43
    DBUG_PRINT("note",("Packet too short: Not compressed"));
 
44
  }
 
45
  else
 
46
  {
 
47
    uchar *compbuf=my_compress_alloc(packet,len,complen);
 
48
    if (!compbuf)
 
49
      DBUG_RETURN(*complen ? 0 : 1);
 
50
    memcpy(packet,compbuf,*len);
 
51
    my_free(compbuf,MYF(MY_WME));
 
52
  }
 
53
  DBUG_RETURN(0);
 
54
}
 
55
 
 
56
 
 
57
uchar *my_compress_alloc(const uchar *packet, size_t *len, size_t *complen)
 
58
{
 
59
  uchar *compbuf;
 
60
  uLongf tmp_complen;
 
61
  int res;
 
62
  *complen=  *len * 120 / 100 + 12;
 
63
 
 
64
  if (!(compbuf= (uchar *) my_malloc(*complen, MYF(MY_WME))))
 
65
    return 0;                                   /* Not enough memory */
 
66
 
 
67
  tmp_complen= *complen;
 
68
  res= compress((Bytef*) compbuf, &tmp_complen, (Bytef*) packet, (uLong) *len);
 
69
  *complen=    tmp_complen;
 
70
 
 
71
  if (res != Z_OK)
 
72
  {
 
73
    my_free(compbuf, MYF(MY_WME));
 
74
    return 0;
 
75
  }
 
76
 
 
77
  if (*complen >= *len)
 
78
  {
 
79
    *complen= 0;
 
80
    my_free(compbuf, MYF(MY_WME));
 
81
    DBUG_PRINT("note",("Packet got longer on compression; Not compressed"));
 
82
    return 0;
 
83
  }
 
84
  /* Store length of compressed packet in *len */
 
85
  swap_variables(size_t, *len, *complen);
 
86
  return compbuf;
 
87
}
 
88
 
 
89
 
 
90
/*
 
91
  Uncompress packet
 
92
 
 
93
   SYNOPSIS
 
94
     my_uncompress()
 
95
     packet     Compressed data. This is is replaced with the orignal data.
 
96
     len        Length of compressed data
 
97
     complen    Length of the packet buffer (must be enough for the original
 
98
                data)
 
99
 
 
100
   RETURN
 
101
     1   error
 
102
     0   ok.  In this case 'complen' contains the updated size of the
 
103
              real data.
 
104
*/
 
105
 
 
106
my_bool my_uncompress(uchar *packet, size_t len, size_t *complen)
 
107
{
 
108
  uLongf tmp_complen;
 
109
  DBUG_ENTER("my_uncompress");
 
110
 
 
111
  if (*complen)                                 /* If compressed */
 
112
  {
 
113
    uchar *compbuf= (uchar *) my_malloc(*complen,MYF(MY_WME));
 
114
    int error;
 
115
    if (!compbuf)
 
116
      DBUG_RETURN(1);                           /* Not enough memory */
 
117
 
 
118
    tmp_complen= *complen;
 
119
    error= uncompress((Bytef*) compbuf, &tmp_complen, (Bytef*) packet,
 
120
                      (uLong) len);
 
121
    *complen= tmp_complen;
 
122
    if (error != Z_OK)
 
123
    {                                           /* Probably wrong packet */
 
124
      DBUG_PRINT("error",("Can't uncompress packet, error: %d",error));
 
125
      my_free(compbuf, MYF(MY_WME));
 
126
      DBUG_RETURN(1);
 
127
    }
 
128
    memcpy(packet, compbuf, *complen);
 
129
    my_free(compbuf, MYF(MY_WME));
 
130
  }
 
131
  else
 
132
    *complen= len;
 
133
  DBUG_RETURN(0);
 
134
}
 
135
 
 
136
/*
 
137
  Internal representation of the frm blob is:
 
138
 
 
139
  ver     4 bytes
 
140
  orglen  4 bytes
 
141
  complen 4 bytes
 
142
*/
 
143
 
 
144
#define BLOB_HEADER 12
 
145
 
 
146
 
 
147
/*
 
148
  packfrm is a method used to compress the frm file for storage in a
 
149
  handler. This method was developed for the NDB handler and has been moved
 
150
  here to serve also other uses.
 
151
 
 
152
  SYNOPSIS
 
153
    packfrm()
 
154
    data                    Data reference to frm file data.
 
155
    len                     Length of frm file data
 
156
    out:pack_data           Reference to the pointer to the packed frm data
 
157
    out:pack_len            Length of packed frm file data
 
158
 
 
159
  NOTES
 
160
    data is replaced with compressed content
 
161
 
 
162
  RETURN VALUES
 
163
    0                       Success
 
164
    >0                      Failure
 
165
*/
 
166
 
 
167
int packfrm(uchar *data, size_t len,
 
168
            uchar **pack_data, size_t *pack_len)
 
169
{
 
170
  int error;
 
171
  size_t org_len, comp_len, blob_len;
 
172
  uchar *blob;
 
173
  DBUG_ENTER("packfrm");
 
174
  DBUG_PRINT("enter", ("data: 0x%lx  len: %lu", (long) data, (ulong) len));
 
175
 
 
176
  error= 1;
 
177
  org_len= len;
 
178
  if (my_compress((uchar*)data, &org_len, &comp_len))
 
179
    goto err;
 
180
 
 
181
  DBUG_PRINT("info", ("org_len: %lu  comp_len: %lu", (ulong) org_len,
 
182
                      (ulong) comp_len));
 
183
  DBUG_DUMP("compressed", data, org_len);
 
184
 
 
185
  error= 2;
 
186
  blob_len= BLOB_HEADER + org_len;
 
187
  if (!(blob= (uchar*) my_malloc(blob_len,MYF(MY_WME))))
 
188
    goto err;
 
189
 
 
190
  /* Store compressed blob in machine independent format */
 
191
  int4store(blob, 1);
 
192
  int4store(blob+4, (uint32) len);
 
193
  int4store(blob+8, (uint32) org_len);          /* compressed length */
 
194
 
 
195
  /* Copy frm data into blob, already in machine independent format */
 
196
  memcpy(blob+BLOB_HEADER, data, org_len);
 
197
 
 
198
  *pack_data= blob;
 
199
  *pack_len=  blob_len;
 
200
  error= 0;
 
201
 
 
202
  DBUG_PRINT("exit", ("pack_data: 0x%lx  pack_len: %lu",
 
203
                      (long) *pack_data, (ulong) *pack_len));
 
204
err:
 
205
  DBUG_RETURN(error);
 
206
 
 
207
}
 
208
 
 
209
/*
 
210
  unpackfrm is a method used to decompress the frm file received from a
 
211
  handler. This method was developed for the NDB handler and has been moved
 
212
  here to serve also other uses for other clustered storage engines.
 
213
 
 
214
  SYNOPSIS
 
215
    unpackfrm()
 
216
    pack_data               Data reference to packed frm file data
 
217
    out:unpack_data         Reference to the pointer to the unpacked frm data
 
218
    out:unpack_len          Length of unpacked frm file data
 
219
 
 
220
  RETURN VALUES¨
 
221
    0                       Success
 
222
    >0                      Failure
 
223
*/
 
224
 
 
225
int unpackfrm(uchar **unpack_data, size_t *unpack_len,
 
226
              const uchar *pack_data)
 
227
{
 
228
   uchar *data;
 
229
   size_t complen, orglen;
 
230
   ulong ver;
 
231
   DBUG_ENTER("unpackfrm");
 
232
   DBUG_PRINT("enter", ("pack_data: 0x%lx", (long) pack_data));
 
233
 
 
234
   ver=         uint4korr(pack_data);
 
235
   orglen=      uint4korr(pack_data+4);
 
236
   complen=     uint4korr(pack_data+8);
 
237
 
 
238
   DBUG_PRINT("blob",("ver: %lu  complen: %lu  orglen: %lu",
 
239
                      ver, (ulong) complen, (ulong) orglen));
 
240
   DBUG_DUMP("blob->data", pack_data + BLOB_HEADER, complen);
 
241
 
 
242
   if (ver != 1)
 
243
     DBUG_RETURN(1);
 
244
   if (!(data= my_malloc(max(orglen, complen), MYF(MY_WME))))
 
245
     DBUG_RETURN(2);
 
246
   memcpy(data, pack_data + BLOB_HEADER, complen);
 
247
 
 
248
   if (my_uncompress(data, complen, &orglen))
 
249
   {
 
250
     my_free(data, MYF(0));
 
251
     DBUG_RETURN(3);
 
252
   }
 
253
 
 
254
   *unpack_data= data;
 
255
   *unpack_len=  orglen;
 
256
 
 
257
   DBUG_PRINT("exit", ("frmdata: 0x%lx  len: %lu", (long) *unpack_data,
 
258
                       (ulong) *unpack_len));
 
259
   DBUG_RETURN(0);
 
260
}