~drizzle-trunk/drizzle/development

1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
1
/* Copyright (c) 2008 PrimeBase Technologies GmbH, Germany
2
 *
3
 * PrimeBase Media Stream for MySQL
4
 *
5
 * This program is free software; you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or
8
 * (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
1802.10.2 by Monty Taylor
Update all of the copyright headers to include the correct address.
17
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
18
 *
19
 * Original author: Paul McCullagh
20
 * Continued development: Barry Leslie
21
 *
22
 * 2007-07-10
23
 *
24
 * H&G2JCtL
25
 *
26
 * Network interface.
27
 *
28
 */
29
1548.2.2 by Barry.Leslie at PrimeBase
A lot of minor changes to clean up the code and to get it to build with Drizzle.
30
#include "cslib/CSConfig.h"
1548.2.26 by Barry.Leslie at PrimeBase
Bug fix for buffer size goof.
31
1802.16.13 by Padraig O'Sullivan
Fixes for pbms compile errors after removing MyBitmap.
32
#include "defs_ms.h"
33
1548.2.2 by Barry.Leslie at PrimeBase
A lot of minor changes to clean up the code and to get it to build with Drizzle.
34
#include "cslib/CSGlobal.h"
35
#include "cslib/CSStrUtil.h"
36
#include "cslib/CSStorage.h"
1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
37
1548.2.10 by Barry.Leslie at PrimeBase
Merge from trunk.
38
#include "compactor_ms.h"
39
#include "open_table_ms.h"
40
#include "repository_ms.h"
1548.2.3 by Barry.Leslie at PrimeBase
Added drizzle event observer class to PBMS as well as a lot of mostly minor changes for drizzle compatability.
41
#include "parameters_ms.h"
1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
42
43
/*
44
 * ---------------------------------------------------------------
45
 * COMPACTOR THREAD
46
 */
47
48
MSCompactorThread::MSCompactorThread(time_t wait_time, MSDatabase *db):
49
CSDaemon(wait_time, NULL),
50
iCompactorDatabase(db)
51
{
52
}
53
54
void MSCompactorThread::close()
55
{
56
}
57
58
bool MSCompactorThread::doWork()
59
{
60
	bool				complete;
61
	MSRepository		*src_repo, *dst_repo;
62
	MSRepoFile			*src_file, *dst_file;
1548.2.2 by Barry.Leslie at PrimeBase
A lot of minor changes to clean up the code and to get it to build with Drizzle.
63
	uint32_t			src_repo_id;
1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
64
	MSBlobHeadRec		blob;
65
	off64_t				src_offset;
1548.2.2 by Barry.Leslie at PrimeBase
A lot of minor changes to clean up the code and to get it to build with Drizzle.
66
	uint16_t			head_size;
67
	uint64_t			blob_size, blob_data_size;
1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
68
	CSStringBuffer		*head;
69
	MSRepoPointersRec	ptr;
1548.2.2 by Barry.Leslie at PrimeBase
A lot of minor changes to clean up the code and to get it to build with Drizzle.
70
	uint32_t				table_ref_count;
71
	uint32_t				blob_ref_count;
1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
72
	int					ref_count;
73
	size_t				ref_size;
1548.2.2 by Barry.Leslie at PrimeBase
A lot of minor changes to clean up the code and to get it to build with Drizzle.
74
	CSMutex				*mylock;
75
	uint32_t			tab_id;
76
	uint64_t			blob_id;
1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
77
	MSOpenTable			*otab;
1548.2.2 by Barry.Leslie at PrimeBase
A lot of minor changes to clean up the code and to get it to build with Drizzle.
78
	uint32_t			repo_id;
79
	uint64_t			repo_offset;
80
	uint64_t			repo_blob_size;
81
	uint16_t			repo_head_size;
82
	uint16_t			tab_index;
1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
83
	uint8_t				status;
84
85
	enter_();
86
	retry:
87
	
88
#ifdef MS_COMPACTOR_POLLS
89
	if (!(src_repo = iCompactorDatabase->getRepoFullOfTrash(NULL)))
90
		return_(true);
91
#else
92
	myWaitTime = MS_DEFAULT_COMPACTOR_WAIT * 1000;  // Time in milli-seconds
93
	if (!(src_repo = iCompactorDatabase->getRepoFullOfTrash(&myWaitTime)))
94
		return_(true);
95
#endif
96
	frompool_(src_repo);
97
	src_file = src_repo->openRepoFile();
98
	push_(src_file);
99
100
	dst_repo = iCompactorDatabase->lockRepo(src_repo->myRepoFileSize - src_repo->myGarbageCount);
101
	frompool_(dst_repo);
102
	dst_file = dst_repo->openRepoFile();
103
	push_(dst_file);
104
105
	new_(head, CSStringBuffer(100));
106
	push_(head);
107
108
	complete = false;
109
	src_repo_id = src_repo->myRepoID;
110
	src_offset = src_repo->myRepoHeadSize;
111
	//printf("\nCompacting repo %"PRId32"\n\n", src_repo_id);
112
	// For testing:
113
	{
114
		int blockit = 0;
115
		if (blockit) {
116
			release_(head);
117
			release_(dst_file);
118
			backtopool_(dst_repo);
119
			release_(src_file);
120
			backtopool_(src_repo);
121
122
			myWaitTime = 5 * 1000;  // Time in milli-seconds
123
			return_(true);
124
		}
125
	}
126
	while (src_offset < src_repo->myRepoFileSize) {			
127
		retry_loop:
128
		suspended();
129
130
		if (myMustQuit)
131
			goto quit;
132
		retry_read:
133
		
134
		// A lock is required here because references and dereferences to the
135
		// BLOBs can result in the repository record being updated while 
136
		// it is being copied.
1548.2.2 by Barry.Leslie at PrimeBase
A lot of minor changes to clean up the code and to get it to build with Drizzle.
137
		mylock = &src_repo->myRepoLock[src_offset % CS_REPO_REC_LOCK_COUNT];
138
		lock_(mylock);
1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
139
		if (src_file->read(&blob, src_offset, src_repo->myRepoBlobHeadSize, 0) < src_repo->myRepoBlobHeadSize) {
1548.2.2 by Barry.Leslie at PrimeBase
A lot of minor changes to clean up the code and to get it to build with Drizzle.
140
			unlock_(mylock);
1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
141
			break;
142
		}
143
		ref_size = CS_GET_DISK_1(blob.rb_ref_size_1);
144
		ref_count = CS_GET_DISK_2(blob.rb_ref_count_2);
145
		head_size = CS_GET_DISK_2(blob.rb_head_size_2);
146
		blob_size = CS_GET_DISK_6(blob.rb_blob_repo_size_6);
147
		blob_data_size = CS_GET_DISK_6(blob.rb_blob_data_size_6);
148
		status = CS_GET_DISK_1(blob.rb_status_1);
149
		if ((blob_data_size == 0) || ref_count <= 0 || ref_size == 0 ||
150
			head_size < src_repo->myRepoBlobHeadSize + ref_count * ref_size ||
151
			!VALID_BLOB_STATUS(status)) {
152
			/* Can't be true. Assume this is garbage! */
1548.2.2 by Barry.Leslie at PrimeBase
A lot of minor changes to clean up the code and to get it to build with Drizzle.
153
			unlock_(mylock);
1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
154
			src_offset++;
155
			goto retry_read;
156
		}
157
		if (IN_USE_BLOB_STATUS(status)) {
158
			head->setLength(head_size);
159
			if (src_file->read(head->getBuffer(0), src_offset, head_size, 0) != head_size) {
1548.2.2 by Barry.Leslie at PrimeBase
A lot of minor changes to clean up the code and to get it to build with Drizzle.
160
				unlock_(mylock);
1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
161
				break;
162
			}
163
164
			table_ref_count = 0;
165
			blob_ref_count = 0;
166
			
167
			ptr.rp_chars = head->getBuffer(0) + src_repo->myRepoBlobHeadSize;
168
			for (int count = 0; count < ref_count; count++) {
169
				switch (CS_GET_DISK_2(ptr.rp_ref->rr_type_2)) {
170
					case MS_BLOB_FREE_REF:
171
						break;
172
					case MS_BLOB_TABLE_REF:
173
						/* Check the reference: */
174
						tab_id = CS_GET_DISK_4(ptr.rp_tab_ref->tr_table_id_4);
175
						blob_id = CS_GET_DISK_6(ptr.rp_tab_ref->tr_blob_id_6);
176
177
						otab = MSTableList::getOpenTableByID(iCompactorDatabase->myDatabaseID, tab_id);
178
						if (otab) {
179
							frompool_(otab);
180
							/* Ignore the return value (it will fail because auth_code is wrong!)!! */
181
							uint32_t auth_code = 0;
182
							otab->getDBTable()->readBlobHandle(otab, blob_id, &auth_code, &repo_id, &repo_offset, &repo_blob_size, &repo_head_size, false);
183
							backtopool_(otab);
184
							if (repo_id == src_repo_id &&
185
								repo_offset == src_offset &&
186
								repo_blob_size == blob_data_size &&
187
								repo_head_size == head_size)
188
								table_ref_count++;
189
							else
190
								/* Remove the reference: */
191
								CS_SET_DISK_2(ptr.rp_ref->rr_type_2, MS_BLOB_FREE_REF);
192
						}
193
						else
194
							CS_SET_DISK_2(ptr.rp_ref->rr_type_2, MS_BLOB_FREE_REF);
195
						break;
196
					case MS_BLOB_DELETE_REF:
197
						/* These are temporary references from the TempLog file. */
198
						/* We try to prevent this from happening, but it can! */
199
						uint32_t			temp_log_id;
200
						uint32_t			temp_log_offset;
201
						MSTempLogFile	*temp_log;
202
203
						temp_log_id = CS_GET_DISK_4(ptr.rp_temp_ref->tp_log_id_4);
204
						temp_log_offset = CS_GET_DISK_4(ptr.rp_temp_ref->tp_offset_4);
205
						if ((temp_log = iCompactorDatabase->openTempLogFile(temp_log_id, NULL, NULL))) {
206
							MSTempLogItemRec	log_item;
207
							uint32_t				then;
208
							time_t				now;
209
210
							push_(temp_log);
211
							if (temp_log->read(&log_item, temp_log_offset, sizeof(MSTempLogItemRec), 0) == sizeof(MSTempLogItemRec)) {
212
								then = CS_GET_DISK_4(log_item.ti_time_4);
213
								now = time(NULL);
1548.2.3 by Barry.Leslie at PrimeBase
Added drizzle event observer class to PBMS as well as a lot of mostly minor changes for drizzle compatability.
214
								if (now < (time_t)(then + PBMSParameters::getTempBlobTimeout())) {
1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
215
									/* Wait for the BLOB to expire before we continue: */									
216
									release_(temp_log);
1548.2.2 by Barry.Leslie at PrimeBase
A lot of minor changes to clean up the code and to get it to build with Drizzle.
217
									unlock_(mylock);
1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
218
219
									/* Go to sleep until the problem has gone away! */
220
									lock_(this);
221
									suspendedWait(MSTempLog::adjustWaitTime(then, now));
222
									unlock_(this);
223
									goto retry_loop;
224
								}
225
							}
226
							release_(temp_log);
227
						}
228
229
						/* Remove the temp reference: */
230
						CS_SET_DISK_2(ptr.rp_ref->rr_type_2, MS_BLOB_FREE_REF);
231
						break;
232
					default:
233
						tab_index = CS_GET_DISK_2(ptr.rp_blob_ref->er_table_2);
234
						if (tab_index > ref_count || !tab_index) {
235
							/* Can't be true. Assume this is garbage! */
1548.2.2 by Barry.Leslie at PrimeBase
A lot of minor changes to clean up the code and to get it to build with Drizzle.
236
							unlock_(mylock);
1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
237
							src_offset++;
238
							goto retry_read;
239
						}
240
						blob_ref_count++;
241
						break;
242
				}
243
				ptr.rp_chars += ref_size;
244
			}
245
246
			if (table_ref_count && blob_ref_count) {
247
				/* Check the blob references again to make sure that they
248
				 * refer to valid table references.
249
				 */
250
				MSRepoTableRefPtr	tab_ref;
251
252
				blob_ref_count = 0;
253
				ptr.rp_chars = head->getBuffer(0) + src_repo->myRepoBlobHeadSize;
254
				for (int count = 0; count < ref_count; count++) {
255
					switch (CS_GET_DISK_2(ptr.rp_ref->rr_type_2)) {
256
						case MS_BLOB_FREE_REF:
257
						case MS_BLOB_TABLE_REF:
258
						case MS_BLOB_DELETE_REF:
259
							break;
260
						default: // If it isn't one of the above we assume it is an blob ref. (er_table_2 can never have a value equal to one of the above REF type flags.)
261
								// It was already verified above that the index was with in range.
262
							tab_ref = (MSRepoTableRefPtr) (head->getBuffer(0) + src_repo->myRepoBlobHeadSize + (CS_GET_DISK_2(ptr.rp_blob_ref->er_table_2)-1) * ref_size);
263
							if (CS_GET_DISK_2(tab_ref->rr_type_2) == MS_BLOB_TABLE_REF)
264
								blob_ref_count++;
265
							break;
266
					}
267
					ptr.rp_chars += ref_size;
268
				}
269
			}
270
271
			if (blob_ref_count) {
272
				off64_t dst_offset;
273
274
				dst_offset = dst_repo->myRepoFileSize;
275
276
				/* Write the header. */
277
				dst_file->write(head->getBuffer(0), dst_offset, head_size);
278
279
				/* We have an engine reference, copy the BLOB over: */
1841.1.3 by Barry.Leslie at PrimeBase
Merged changes from lp:pbms. These changes should remove any danger
280
				CSFile::transfer(RETAIN(dst_file), dst_offset + head_size, RETAIN(src_file), src_offset + head_size, blob_size, iCompactBuffer, MS_COMPACTOR_BUFFER_SIZE);
1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
281
282
#ifdef HAVE_ALIAS_SUPPORT
283
				/* If the BLOB has an alias update the alias index. */
284
				if (CS_GET_DISK_2(blob.rb_alias_offset_2)) {
285
					iCompactorDatabase->moveBlobAlias( src_repo_id, src_offset, CS_GET_DISK_4(blob.rb_alias_hash_4), dst_repo->myRepoID, dst_offset);
286
				}
287
#endif				
288
				/* Update the references: */
289
				ptr.rp_chars = head->getBuffer(0) + src_repo->myRepoBlobHeadSize;
290
				for (int count = 0; count < ref_count; count++) {
291
					switch (CS_GET_DISK_2(ptr.rp_ref->rr_type_2)) {
292
						case MS_BLOB_FREE_REF:
293
							break;
294
						case MS_BLOB_TABLE_REF:
295
							tab_id = CS_GET_DISK_4(ptr.rp_tab_ref->tr_table_id_4);
296
							blob_id = CS_GET_DISK_6(ptr.rp_tab_ref->tr_blob_id_6);
297
298
							if ((otab = MSTableList::getOpenTableByID(iCompactorDatabase->myDatabaseID, tab_id))) {
299
								frompool_(otab);
300
								otab->getDBTable()->updateBlobHandle(otab, blob_id, dst_repo->myRepoID, dst_offset, 0);
301
								backtopool_(otab);
302
							}
303
							break;
304
						case MS_BLOB_DELETE_REF:
305
							break;
306
						default:
307
							break;
308
					}
309
					ptr.rp_chars += ref_size;
310
				}
311
312
				dst_repo->myRepoFileSize += head_size + blob_size;
313
			}
314
		}
315
		
1548.2.2 by Barry.Leslie at PrimeBase
A lot of minor changes to clean up the code and to get it to build with Drizzle.
316
		unlock_(mylock);
1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
317
		src_offset += head_size + blob_size;
318
	}
319
320
	src_repo->mustBeDeleted = true;
321
	complete = true;
322
323
	quit:
324
	release_(head);
325
	release_(dst_file);
326
	backtopool_(dst_repo);
327
	release_(src_file);
328
	backtopool_(src_repo);
329
330
	if (complete)
331
		iCompactorDatabase->removeRepo(src_repo_id, &myMustQuit);
332
333
	if (!myMustQuit)
334
		goto retry;
335
	return_(true);
336
}
337
1548.2.11 by Barry.Leslie at PrimeBase
Removed libxml reqirement by using a home grown xml parser.
338
void *MSCompactorThread::completeWork()
1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
339
{
340
	close();
341
	return NULL;
1548.2.2 by Barry.Leslie at PrimeBase
A lot of minor changes to clean up the code and to get it to build with Drizzle.
342
}
1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
343