CUBRID Engine  latest
log_compress.c
Go to the documentation of this file.
1 /*
2  * Copyright 2008 Search Solution Corporation
3  * Copyright 2016 CUBRID Corporation
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 /*
20  * log_compress.c - log compression functions
21  *
22  * Note: Using lz4 library
23  */
24 
25 #ident "$Id$"
26 
27 #include <string.h>
28 #include <assert.h>
29 
30 #include "log_compress.h"
31 #include "error_manager.h"
32 #include "memory_alloc.h"
33 #include "perf_monitor.h"
34 
35 /*
36  * log_zip - compress(zip) log data into LOG_ZIP
37  * return: true on success, false on failure
38  * log_zip(in/out): LOG_ZIP structure allocated by log_zip_alloc
39  * length(in): length of given data
40  * data(in): log data to be compressed
41  */
42 bool
43 log_zip (LOG_ZIP * log_zip, LOG_ZIP_SIZE_T length, const void *data)
44 {
45  int zip_len = 0;
46  LOG_ZIP_SIZE_T buf_size;
47  bool compressed;
48 #if defined (SERVER_MODE) || defined (SA_MODE)
49  PERF_UTIME_TRACKER time_track;
50 #endif
51 
52  assert (length > 0 && data != NULL);
53  assert (log_zip != NULL);
54 
55  if (length > LZ4_MAX_INPUT_SIZE)
56  {
57  /* Can't compress beyonds max LZ4 max input size. */
58  return false;
59  }
60 
61  log_zip->data_length = 0;
62 
63  buf_size = LOG_ZIP_BUF_SIZE (length);
64  if (buf_size > log_zip->buf_size)
65  {
66  if (log_zip->log_data)
67  {
68  free_and_init (log_zip->log_data);
69  }
70 
71  log_zip->log_data = (char *) malloc (buf_size);
72  if (log_zip->log_data == NULL)
73  {
75  }
76  log_zip->buf_size = buf_size;
77  }
78 
79  if (log_zip->log_data == NULL)
80  {
81  log_zip->data_length = 0;
82  log_zip->buf_size = 0;
83  return false;
84  }
85 
86 #if defined (SERVER_MODE) || defined (SA_MODE)
87  PERF_UTIME_TRACKER_START (NULL, &time_track);
88 #endif
89 
90  compressed = false;
91 
92  /* save original data length */
93  memcpy (log_zip->log_data, &length, sizeof (LOG_ZIP_SIZE_T));
94 
95  zip_len =
96  LZ4_compress_default ((const char *) data, log_zip->log_data + sizeof (LOG_ZIP_SIZE_T), length,
97  buf_size - sizeof (LOG_ZIP_SIZE_T));
98  if (zip_len > 0)
99  {
100  log_zip->data_length = (LOG_ZIP_SIZE_T) zip_len + sizeof (LOG_ZIP_SIZE_T);
101  /* if the compressed data length >= orginal length, then it means that compression failed */
102  if (log_zip->data_length < length)
103  {
104  compressed = true;
105  }
106  }
107 
108 #if defined (SERVER_MODE) || defined (SA_MODE)
109  PERF_UTIME_TRACKER_TIME (NULL, &time_track, PSTAT_LOG_LZ4_COMPRESS_TIME_COUNTERS);
110 #endif
111 
112  return compressed;
113 }
114 
115 /*
116  * log_unzip - decompress(unzip) log data into LOG_ZIP
117  * return: true on success, false on failure
118  * log_unzip(out): LOG_ZIP structure allocated by log_zip_alloc
119  * length(in): length of given data
120  * data(out): compressed log data
121  */
122 bool
123 log_unzip (LOG_ZIP * log_unzip, LOG_ZIP_SIZE_T length, void *data)
124 {
125  int unzip_len;
126  LOG_ZIP_SIZE_T buf_size;
127  bool decompressed;
128 #if defined (SERVER_MODE) || defined (SA_MODE)
129  PERF_UTIME_TRACKER time_track;
130 #endif
131 
132  assert (length > 0 && data != NULL);
133  assert (log_unzip != NULL);
134 
135  /* get original legnth from the compressed data */
136  memcpy (&buf_size, data, sizeof (LOG_ZIP_SIZE_T));
137 
138  if (buf_size <= 0)
139  {
140  return false;
141  }
142 
143  length -= sizeof (LOG_ZIP_SIZE_T);
144 
145  if (buf_size > log_unzip->buf_size)
146  {
147  if (log_unzip->log_data)
148  {
149  free_and_init (log_unzip->log_data);
150  }
151 
152  log_unzip->log_data = (char *) malloc (buf_size);
153  if (log_unzip->log_data == NULL)
154  {
156  }
157  log_unzip->buf_size = buf_size;
158  }
159 
160  if (log_unzip->log_data == NULL)
161  {
162  log_unzip->data_length = 0;
163  log_unzip->buf_size = 0;
164  return false;
165  }
166 
167 #if defined (SERVER_MODE) || defined (SA_MODE)
168  PERF_UTIME_TRACKER_START (NULL, &time_track);
169 #endif
170 
171  decompressed = false;
172 
173  unzip_len =
174  LZ4_decompress_safe ((const char *) data + sizeof (LOG_ZIP_SIZE_T), (char *) log_unzip->log_data, length, buf_size);
175  if (unzip_len >= 0)
176  {
177  log_unzip->data_length = (LOG_ZIP_SIZE_T) unzip_len;
178  /* if the uncompressed data length != original length, then it means that uncompression failed */
179  if (unzip_len == buf_size)
180  {
181  decompressed = true;
182  }
183  }
184 
185 #if defined (SERVER_MODE) || defined (SA_MODE)
186  PERF_UTIME_TRACKER_TIME (NULL, &time_track, PSTAT_LOG_LZ4_DECOMPRESS_TIME_COUNTERS);
187 #endif
188 
189  return decompressed;
190 }
191 
192 /*
193  * log_diff - make log diff - redo data XORed with undo data
194  * return: true
195  * undo_length(in): length of undo data
196  * undo_data(in): undo log data
197  * redo_length(in): length of redo data
198  * redo_data(in/out) redo log data; set as side effect
199  */
200 bool
201 log_diff (LOG_ZIP_SIZE_T undo_length, const void *undo_data, LOG_ZIP_SIZE_T redo_length, void *redo_data)
202 {
203  LOG_ZIP_SIZE_T i, size;
204  unsigned char *p, *q;
205 
206  assert (undo_length > 0 && undo_data != NULL);
207  assert (redo_length > 0 && redo_data != NULL);
208 
209  size = MIN (undo_length, redo_length);
210 
211  /* redo = redo xor undo */
212  p = (unsigned char *) redo_data;
213  q = (unsigned char *) undo_data;
214  for (i = 0; i < size; i++)
215  {
216  *(p++) ^= *(q++);
217  }
218 
219  return true;
220 }
221 
222 /*
223  * log_zip_alloc - allocate LOG_ZIP structure
224  * return: LOG_ZIP structure or NULL if error
225  * length(in): log_zip data buffer to be allocated
226  *
227  * Note:
228  */
229 LOG_ZIP *
231 {
232  LOG_ZIP *log_zip = NULL;
233  LOG_ZIP_SIZE_T buf_size = 0;
234 
235  assert (size <= LZ4_MAX_INPUT_SIZE);
236 
237  buf_size = LOG_ZIP_BUF_SIZE (size);
238  log_zip = (LOG_ZIP *) malloc (sizeof (LOG_ZIP));
239  if (log_zip == NULL)
240  {
242 
243  return NULL;
244  }
245  log_zip->data_length = 0;
246 
247  log_zip->log_data = (char *) malloc ((size_t) buf_size);
248  if (log_zip->log_data == NULL)
249  {
250  free_and_init (log_zip);
252  return NULL;
253  }
254  log_zip->buf_size = buf_size;
255 
256  return log_zip;
257 }
258 
259 /*
260  * log_zip_free - free LOG_ZIP structure
261  * return: none
262  * log_zip(in): LOG_ZIP structure to be freed
263  */
264 void
266 {
267  assert (log_zip != NULL);
268  if (log_zip->log_data)
269  {
270  free_and_init (log_zip->log_data);
271  }
272 
273  free_and_init (log_zip);
274 }
#define LOG_ZIP_SIZE_T
Definition: log_compress.h:46
#define LOG_ZIP_BUF_SIZE(length)
Definition: log_compress.h:43
LOG_ZIP_SIZE_T data_length
Definition: log_compress.h:55
LOG_ZIP * log_zip_alloc(LOG_ZIP_SIZE_T size)
Definition: log_compress.c:230
char * log_data
Definition: log_compress.h:57
void er_set(int severity, const char *file_name, const int line_no, int err_id, int num_args,...)
#define assert(x)
#define ER_OUT_OF_VIRTUAL_MEMORY
Definition: error_code.h:50
#define NULL
Definition: freelistheap.h:34
#define ARG_FILE_LINE
Definition: error_manager.h:44
bool log_unzip(LOG_ZIP *log_unzip, LOG_ZIP_SIZE_T length, void *data)
Definition: log_compress.c:123
bool log_zip(LOG_ZIP *log_zip, LOG_ZIP_SIZE_T length, const void *data)
Definition: log_compress.c:43
void log_zip_free(LOG_ZIP *log_zip)
Definition: log_compress.c:265
#define free_and_init(ptr)
Definition: memory_alloc.h:147
bool log_diff(LOG_ZIP_SIZE_T undo_length, const void *undo_data, LOG_ZIP_SIZE_T redo_length, void *redo_data)
Definition: log_compress.c:201
int i
Definition: dynamic_load.c:954
LOG_ZIP_SIZE_T buf_size
Definition: log_compress.h:56
const char ** p
Definition: dynamic_load.c:945