/[MITgcm]/mitgcm.org/devel/buildweb/pkg/swish-e/src/btree.c
ViewVC logotype

Contents of /mitgcm.org/devel/buildweb/pkg/swish-e/src/btree.c

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.1.1.1 - (show annotations) (download) (vendor branch)
Fri Sep 20 19:47:29 2002 UTC (22 years, 10 months ago) by adcroft
Branch: Import, MAIN
CVS Tags: baseline, HEAD
Changes since 1.1: +0 -0 lines
File MIME type: text/plain
Error occurred while calculating annotation data.
Importing web-site building process.

1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4
5 #include "swish.h"
6 #include "string.h"
7 #include "compress.h"
8
9 /*
10 #define STANDALONE
11 #define DEBUG
12 */
13
14 #ifdef STANDALONE
15 /* Compress a number and writes it to a buffer */
16 /* buffer must be previously allocated */
17 /* returns the incrmented buffer pointer after storing the compressed number in it */
18 unsigned char *compress3(int num, unsigned char *buffer)
19 {
20 int _i = 0,
21 _r = num;
22 unsigned char _s[MAXINTCOMPSIZE];
23
24 while (_r)
25 {
26 _s[_i++] = _r & 127;
27 _r >>= 7;
28 }
29 while (--_i >= 0)
30 *buffer++ = (_s[_i] | (_i ? 128 : 0));
31
32 return buffer;
33 }
34
35 /* same routine but this works with a memory forward buffer instead of file */
36 /* it also increases the buffer pointer */
37 int uncompress2(unsigned char **buffer)
38 {
39 int _c;
40 int num = 0;
41 unsigned char *p = *buffer;
42
43 do
44 {
45 _c = (int) ((unsigned char) *p++);
46 num <<= 7;
47 num |= _c & 127;
48 if (!num)
49 break;
50 }
51 while (_c & 128);
52
53 *buffer = p;
54 return num;
55 }
56
57
58 /* Rourtines to make long integers portable */
59 unsigned long PACKLONG(unsigned long num)
60 {
61 unsigned long _i = 0L;
62 unsigned char *_s;
63
64 if (num)
65 {
66 _s = (unsigned char *) &_i;
67 _s[0] = (unsigned char) ((num >> 24) & 0xFF);
68 _s[1] = (unsigned char) ((num >> 16) & 0xFF);
69 _s[2] = (unsigned char) ((num >> 8) & 0xFF);
70 _s[3] = (unsigned char) (num & 0xFF);
71 return _i;
72 }
73 return num;
74 }
75
76
77 unsigned long UNPACKLONG(unsigned long num)
78 {
79 unsigned char *_s = (unsigned char *) &num;
80
81 return (_s[0] << 24) + (_s[1] << 16) + (_s[2] << 8) + _s[3];
82 }
83
84
85 char *emalloc(unsigned int size)
86 {
87 return malloc(size);
88 }
89
90 void efree(void *p)
91 {
92 free(p);
93 }
94
95
96 #else
97
98 #include "mem.h"
99
100 unsigned long PACKLONG(unsigned long num);
101 unsigned long UNPACKLONG(unsigned long num);
102 unsigned char *compress3(int num, unsigned char *buffer);
103 int uncompress2(unsigned char **buffer);
104
105 #endif /* STANDALONE */
106
107
108 #include "btree.h"
109
110
111 /* A BTREE page cannot be smaller than BTREE_MinPageSize */
112 #define BTREE_MinPageSize 4096
113
114 /* A BTREE page can be greater than BTREE_MaxPageSize */
115 #define BTREE_MaxPageSize 65536
116
117 #define SizeInt32 4
118 #define SizeInt16 2
119
120
121 /* Round in BTREE_MinPageSize */
122 #define BTREE_RoundPageSize(n) (((n) + BTREE_MinPageSize - 1) & (~(BTREE_MinPageSize - 1)))
123
124 #define BTREE_PageHeaderSize (6 * SizeInt32)
125
126 #define BTREE_PageData(pg) ((pg)->data + BTREE_PageHeaderSize)
127 #define BTREE_EndData(pg) ((pg)->data + (pg)->data_end)
128 #define BTREE_KeyIndexOffset(data,i) (data + BTREE_PageHeaderSize + (i) * SizeInt16)
129 #define BTREE_KeyDataOffset(pg,i) ((*(BTREE_KeyIndexOffset((pg->data),(i))) <<8) + *(BTREE_KeyIndexOffset((pg->data),(i)) + 1))
130 #define BTREE_KeyData(pg,i) ((pg)->data + BTREE_KeyDataOffset((pg),(i)))
131
132 #define BTREE_SetNextPage(pg,num) ( *(int *)((pg)->data + 0 * SizeInt32) = PACKLONG(num))
133 #define BTREE_SetPrevPage(pg,num) ( *(int *)((pg)->data + 1 * SizeInt32) = PACKLONG(num))
134 #define BTREE_SetSize(pg,num) ( *(int *)((pg)->data + 2 * SizeInt32) = PACKLONG(num))
135 #define BTREE_SetNumKeys(pg,num) ( *(int *)((pg)->data + 3 * SizeInt32) = PACKLONG(num))
136 #define BTREE_SetFlags(pg,num) ( *(int *)((pg)->data + 4 * SizeInt32) = PACKLONG(num))
137 #define BTREE_SetDataEnd(pg,num) ( *(int *)((pg)->data + 5 * SizeInt32) = PACKLONG(num))
138
139 #define BTREE_GetNextPage(pg,num) ( (num) = UNPACKLONG(*(int *)((pg)->data + 0 * SizeInt32)))
140 #define BTREE_GetPrevPage(pg,num) ( (num) = UNPACKLONG(*(int *)((pg)->data + 1 * SizeInt32)))
141 #define BTREE_GetSize(pg,num) ( (num) = UNPACKLONG(*(int *)((pg)->data + 2 * SizeInt32)))
142 #define BTREE_GetNumKeys(pg,num) ( (num) = UNPACKLONG(*(int *)((pg)->data + 3 * SizeInt32)))
143 #define BTREE_GetFlags(pg,num) ( (num) = UNPACKLONG(*(int *)((pg)->data + 4 * SizeInt32)))
144 #define BTREE_GetDataEnd(pg,num) ( (num) = UNPACKLONG(*(int *)((pg)->data + 5 * SizeInt32)))
145
146 /* Flags */
147 #define BTREE_ROOT_NODE 0x1
148 #define BTREE_LEAF_NODE 0x2
149
150
151 int BTREE_WritePageToDisk(FILE *fp, BTREE_Page *pg)
152 {
153 BTREE_SetNextPage(pg,pg->next);
154 BTREE_SetPrevPage(pg,pg->prev);
155 BTREE_SetSize(pg,pg->size);
156 BTREE_SetNumKeys(pg,pg->n);
157 BTREE_SetFlags(pg,pg->flags);
158 BTREE_SetDataEnd(pg,pg->data_end);
159 fseek(fp,pg->page_number * BTREE_MinPageSize,SEEK_SET);
160 return fwrite(pg->data,pg->size,1,fp);
161 }
162
163 int BTREE_WritePage(BTREE *b, BTREE_Page *pg)
164 {
165 int hash = pg->page_number % BTREE_CACHE_SIZE;
166 BTREE_Page *tmp;
167 pg->modified =1;
168 if((tmp = b->cache[hash]))
169 {
170 while(tmp)
171 {
172 if(tmp->page_number == pg->page_number)
173 {
174 return 0;
175 }
176 tmp = tmp->next_cache;
177 }
178 }
179 pg->next_cache = b->cache[hash];
180 b->cache[hash] = pg;
181 return 0;
182 }
183
184 int BTREE_FlushCache(BTREE *b)
185 {
186 int i;
187 BTREE_Page *tmp, *next;
188 for(i = 0; i < BTREE_CACHE_SIZE; i++)
189 {
190 if((tmp = b->cache[i]))
191 {
192 while(tmp)
193 {
194 #ifdef DEBUG
195 if(tmp->in_use)
196 {
197 printf("DEBUG Error in FlushCache: Page in use\n");
198 exit(0);
199 }
200 #endif
201 next = tmp->next_cache;
202 if(tmp->modified)
203 {
204 BTREE_WritePageToDisk(b->fp, tmp);
205 tmp->modified = 0;
206 }
207 if(tmp != b->cache[i])
208 efree(tmp);
209 tmp = next;
210 }
211 b->cache[i]->next_cache = NULL;
212 }
213 }
214 return 0;
215 }
216
217 int BTREE_CleanCache(BTREE *b)
218 {
219 int i;
220 BTREE_Page *tmp,*next;
221 for(i = 0; i < BTREE_CACHE_SIZE; i++)
222 {
223 if((tmp = b->cache[i]))
224 {
225 while(tmp)
226 {
227 next = tmp->next_cache;
228 efree(tmp);
229 tmp = next;
230 }
231 b->cache[i] = NULL;
232 }
233 }
234 return 0;
235 }
236
237 BTREE_Page *BTREE_ReadPageFromDisk(FILE *fp, unsigned long page_number)
238 {
239 BTREE_Page *pg = (BTREE_Page *)emalloc(sizeof(BTREE_Page) + BTREE_MinPageSize);
240
241 fseek(fp,page_number * BTREE_MinPageSize,SEEK_SET);
242 fread(pg->data,BTREE_MinPageSize, 1, fp);
243
244 BTREE_GetNextPage(pg,pg->next);
245 BTREE_GetPrevPage(pg,pg->prev);
246 BTREE_GetSize(pg,pg->size);
247 BTREE_GetNumKeys(pg,pg->n);
248 BTREE_GetFlags(pg,pg->flags);
249 BTREE_GetDataEnd(pg,pg->data_end);
250
251 pg->page_number = page_number;
252 pg->modified = 0;
253 return pg;
254 }
255
256 BTREE_Page *BTREE_ReadPage(BTREE *b, unsigned long page_number)
257 {
258 int hash = page_number % BTREE_CACHE_SIZE;
259 BTREE_Page *tmp;
260 if((tmp = b->cache[hash]))
261 {
262 while(tmp)
263 {
264 if(tmp->page_number == page_number)
265 {
266 return tmp;
267 }
268 tmp = tmp->next_cache;
269 }
270 }
271
272 tmp = BTREE_ReadPageFromDisk(b->fp, page_number);
273 tmp->modified = 0;
274 tmp->in_use = 1;
275 tmp->next_cache = b->cache[hash];
276 b->cache[hash] = tmp;
277 return tmp;
278 }
279
280 BTREE_Page *BTREE_NewPage(BTREE *b, unsigned int size, unsigned int flags)
281 {
282 BTREE_Page *pg;
283 long offset;
284 FILE *fp = b->fp;
285 int hash;
286 /* Round up size */
287 size = BTREE_RoundPageSize(size);
288
289 if(size > BTREE_MaxPageSize)
290 return NULL;
291
292 /* Get file pointer */
293 if(fseek(fp,0,SEEK_END) !=0)
294 {
295 printf("mal\n");
296 }
297 offset = ftell(fp);
298 /* Round up file pointer */
299 offset = BTREE_RoundPageSize(offset);
300
301 /* Set new file pointer - data will be aligned */
302 if(fseek(fp,offset, SEEK_SET)!=0 || offset != ftell(fp))
303 {
304 printf("mal\n");
305 }
306
307 pg = (BTREE_Page *)emalloc(sizeof(BTREE_Page) + size);
308 memset(pg,0,sizeof(BTREE_Page) + size);
309 /* Reserve space in file */
310 if(fwrite(pg->data,1,size,fp)!=size || ((long)size + offset) != ftell(fp))
311 {
312 printf("mal\n");
313 }
314
315 pg->next = 0;
316 pg->prev = 0;
317 pg->size = size;
318 pg->flags = flags;
319 pg->data_end = BTREE_PageHeaderSize;
320 pg->n = 0;
321
322 pg->page_number = offset/BTREE_MinPageSize;
323
324 /* add to cache */
325 pg->modified = 1;
326 pg->in_use = 1;
327 hash = pg->page_number % BTREE_CACHE_SIZE;
328 pg->next_cache = b->cache[hash];
329 b->cache[hash] = pg;
330 return pg;
331 }
332
333 void BTREE_FreePage(BTREE *b, BTREE_Page *pg)
334 {
335 int hash = pg->page_number % BTREE_CACHE_SIZE;
336 BTREE_Page *tmp;
337
338 tmp = b->cache[hash];
339
340 #ifdef DEBUG
341 if(!(tmp = b->cache[hash]))
342 {
343 /* This should never happen!!!! */
344 printf("Error in FreePage\n");
345 exit(0);
346 }
347 #endif
348
349 while(tmp)
350 {
351 if (tmp->page_number != pg->page_number)
352 tmp = tmp->next_cache;
353 else
354 {
355 tmp->in_use = 0;
356 break;
357 }
358 }
359 }
360
361 int BTREE_CompareKeys(unsigned char *key1, int key_len1, unsigned char *key2, int key_len2)
362 {
363 int rc;
364
365 if(key_len1 > key_len2)
366 rc = memcmp(key1,key2,key_len2);
367 else
368 rc = memcmp(key1,key2,key_len1);
369
370 if(!rc)
371 rc = key_len1 - key_len2;
372
373 return rc;
374 }
375
376
377 int BTREE_GetPositionForKey(BTREE_Page *pg, unsigned char *key, int key_len, int *comp)
378 {
379 int i,j,k,isbigger=-1;
380 int key_len_k;
381 unsigned char *key_k;
382 /* Use binary search for adding key */
383 /* Look for the position to insert using a binary search */
384 i = pg->n - 1;
385 j = k = 0;
386 while (i >= j)
387 {
388 k = j + (i - j) / 2;
389 key_k = BTREE_KeyData(pg,k);
390 key_len_k = uncompress2(&key_k);
391 isbigger = BTREE_CompareKeys(key,key_len,key_k,key_len_k);
392 if (!isbigger)
393 break;
394 else if (isbigger > 0)
395 j = k + 1;
396 else
397 i = k - 1;
398 }
399
400 *comp = isbigger;
401
402 return k;
403 }
404
405 unsigned int BTREE_GetKeyFromPage(BTREE *b, BTREE_Page *pg, unsigned char *key, int key_len, unsigned char **found, int *found_len)
406 {
407 int k,comp = 0;
408
409 k = BTREE_GetPositionForKey(pg, key, key_len, &comp);
410
411 if(comp > 0 && k == (int) pg->n && k)
412 k--;
413
414 if(comp < 0 && k)
415 k--;
416
417 b->current_page = pg->page_number;
418 b->current_position = k;
419
420 *found = BTREE_KeyData(pg,k);
421 *found_len = uncompress2(found);
422 return UNPACKLONG(*(unsigned long *) (*found + *found_len));
423 }
424
425 int BTREE_AddKeyToPage(BTREE_Page *pg, int position, unsigned char *key, int key_len, unsigned long data_pointer)
426 {
427 unsigned char buffer[BTREE_MaxPageSize];
428 int j,k;
429 unsigned char *p;
430 unsigned char *new_key_start, *new_key_end;
431 int new_entry_len , tmp;
432
433 data_pointer = PACKLONG(data_pointer);
434
435 k = position;
436
437 /* Write key */
438 /* Write from Page header upto the key being inserted */
439 p = buffer;
440 memcpy(p,pg->data,BTREE_KeyIndexOffset(pg->data,k) - pg->data);
441 p += BTREE_KeyIndexOffset(pg->data,k) - pg->data;
442
443 p += (pg->n - k + 1) * SizeInt16;
444
445 if(k == (int)pg->n)
446 {
447 if(k)
448 {
449 memcpy(p,BTREE_KeyData(pg,0),BTREE_EndData(pg) - BTREE_KeyData(pg,0));
450 p += BTREE_EndData(pg) - BTREE_KeyData(pg,0);
451 }
452 }
453 else
454 {
455 if(k)
456 {
457 memcpy(p,BTREE_KeyData(pg,0),BTREE_KeyData(pg,k) - BTREE_KeyData(pg,0));
458 p += BTREE_KeyData(pg,k) - BTREE_KeyData(pg,0);
459 }
460 }
461
462 new_key_start = p;
463 p = compress3(key_len, p);
464 memcpy(p , key, key_len);
465 p += key_len;
466 memcpy(p, &data_pointer, SizeInt32);
467 p += SizeInt32;
468 new_key_end = p;
469 new_entry_len = new_key_end - new_key_start;
470
471 if(k < (int) pg->n)
472 {
473 memcpy(p,BTREE_KeyData(pg,k), BTREE_EndData(pg) - BTREE_KeyData(pg,k));
474 p += BTREE_EndData(pg) - BTREE_KeyData(pg,k);
475 }
476
477 for(j = 0; j < k; j++)
478 {
479 tmp = BTREE_KeyDataOffset(pg,j) + SizeInt16;
480 *(BTREE_KeyIndexOffset(buffer,j)) = (unsigned char)((tmp & 0xff00) >>8);
481 *(BTREE_KeyIndexOffset(buffer,j) + 1) = (unsigned char) (tmp & 0xff);
482 }
483
484 for(j = (int)(pg->n - 1) ; j >=k; j--)
485 {
486 tmp = BTREE_KeyDataOffset(pg,j) + new_entry_len + SizeInt16;
487 *(BTREE_KeyIndexOffset(buffer,j + 1)) = (unsigned char)((tmp & 0xff00) >>8);
488 *(BTREE_KeyIndexOffset(buffer,j + 1) + 1) = (unsigned char) (tmp & 0xff);
489 }
490
491 tmp = new_key_start - buffer;
492 *(BTREE_KeyIndexOffset(buffer,k)) = (unsigned char)((tmp & 0xff00) >>8);
493 *(BTREE_KeyIndexOffset(buffer,k) + 1) = (unsigned char) (tmp & 0xff);
494
495 memcpy(pg->data, buffer, p - buffer);
496 pg->n++;
497 pg->data_end = p - buffer;
498
499 return k;
500 }
501
502 int BTREE_DelKeyInPage(BTREE_Page *pg, int pos)
503 {
504 unsigned char buffer[BTREE_MaxPageSize];
505 unsigned char *p, *q;
506 unsigned char *del_key_start, *del_key_end;
507 int del_entry_len , tmp;
508 int j, k = pos;
509
510
511
512 /* Write key */
513 /* Write from Page header upto the key being deleted */
514 p = buffer;
515
516 memcpy(p,pg->data,BTREE_KeyIndexOffset(pg->data,k) - pg->data);
517 p += BTREE_KeyIndexOffset(pg->data,k) - pg->data;
518
519 if((k + 1) < (int)pg->n)
520 {
521 memcpy(p,BTREE_KeyIndexOffset(pg->data,k + 1), BTREE_KeyIndexOffset(pg->data,pg->n) - BTREE_KeyIndexOffset(pg->data,k + 1));
522 p += BTREE_KeyIndexOffset(pg->data,pg->n) - BTREE_KeyIndexOffset(pg->data,k + 1);
523 }
524
525
526 if(k)
527 {
528 memcpy(p,BTREE_KeyData(pg,0),BTREE_KeyData(pg,k) - BTREE_KeyData(pg,0));
529 p += BTREE_KeyData(pg,k) - BTREE_KeyData(pg,0);
530 }
531 if((k + 1) < (int)pg->n)
532 {
533 memcpy(p,BTREE_KeyData(pg,k + 1),BTREE_EndData(pg) - BTREE_KeyData(pg,k + 1));
534 p += BTREE_EndData(pg) - BTREE_KeyData(pg,k + 1);
535 }
536
537 /* Compute length of deleted key */
538 del_key_start = q = BTREE_KeyData(pg,k);
539 q += uncompress2(&q);
540 q += SizeInt32;
541 del_key_end = q;
542 del_entry_len = del_key_end - del_key_start;
543
544 for(j = 0; j < k; j++)
545 {
546 tmp = BTREE_KeyDataOffset(pg,j) - SizeInt16;
547 *(BTREE_KeyIndexOffset(buffer,j)) = (unsigned char)((tmp & 0xff00) >>8);
548 *(BTREE_KeyIndexOffset(buffer,j) + 1) = (unsigned char) (tmp & 0xff);
549 }
550
551 for(j = (int)(pg->n - 1) ; j >k; j--)
552 {
553 tmp = BTREE_KeyDataOffset(pg,j) - del_entry_len - SizeInt16;
554 *(BTREE_KeyIndexOffset(buffer,j - 1)) = (unsigned char)((tmp & 0xff00) >>8);
555 *(BTREE_KeyIndexOffset(buffer,j - 1) + 1) = (unsigned char) (tmp & 0xff);
556 }
557
558 memcpy(pg->data, buffer, p - buffer);
559 pg->n--;
560 pg->data_end = p - buffer;
561
562 return k;
563 }
564
565 BTREE *BTREE_New(FILE *fp, unsigned int size)
566 {
567 BTREE *b;
568 int i;
569 b = (BTREE *) emalloc(sizeof(BTREE));
570 b->page_size = size;
571 b->fp = fp;
572 for(i = 0; i < BTREE_CACHE_SIZE; i++)
573 b->cache[i] = NULL;
574
575 return b;
576 }
577
578 BTREE *BTREE_Create(FILE *fp, unsigned int size)
579 {
580 BTREE *b;
581 BTREE_Page *root;
582 /* Round up size */
583 size = BTREE_RoundPageSize(size);
584
585 if(size > BTREE_MaxPageSize)
586 return NULL;
587
588 b = BTREE_New(fp , size);
589 root = BTREE_NewPage(b, size, BTREE_ROOT_NODE | BTREE_LEAF_NODE);
590
591 b->root_page = root->page_number;
592
593 BTREE_WritePage(b, root);
594 BTREE_FreePage(b, root);
595
596 return b;
597 }
598
599
600 BTREE *BTREE_Open(FILE *fp, int size, unsigned long root_page)
601 {
602 BTREE *b;
603 /* Round up size */
604 size = BTREE_RoundPageSize(size);
605
606 if(size > BTREE_MaxPageSize)
607 return NULL;
608
609 b = BTREE_New(fp , size);
610
611 b->root_page = root_page;
612
613 return b;
614 }
615
616 unsigned long BTREE_Close(BTREE *bt)
617 {
618 unsigned long root_page = bt->root_page;
619 BTREE_FlushCache(bt);
620 BTREE_CleanCache(bt);
621 efree(bt);
622 return root_page;
623 }
624
625
626 BTREE_Page *BTREE_Walk(BTREE *b, unsigned char *key, int key_len)
627 {
628 BTREE_Page *pg = BTREE_ReadPage(b, b->root_page);
629 unsigned int i = 0;
630 unsigned long next_page;
631 unsigned char *found;
632 unsigned int found_len;
633 unsigned long father_page;
634
635 b->tree[i++] = 0; /* No father for root */
636
637 father_page = pg->page_number;
638 while(!(pg->flags & BTREE_LEAF_NODE))
639 {
640 next_page = BTREE_GetKeyFromPage(b, pg, key, key_len, &found, &found_len);
641 BTREE_FreePage(b, pg);
642 pg = BTREE_ReadPage(b, next_page);
643 b->tree[i++] = father_page;
644 father_page = pg->page_number;
645 }
646 b->levels = i;
647 return pg;
648 }
649
650 BTREE_Page *BTREE_SplitPage(BTREE *b, BTREE_Page *pg)
651 {
652 BTREE_Page *new_pg = BTREE_NewPage(b, pg->size, pg->flags);
653 int i,n;
654 unsigned char *key_data, *p, *q, *start;
655 int key_len;
656 int tmp;
657
658 n=pg->n / 2;
659
660 /* Key data of new page starts here */
661 p = q = BTREE_KeyIndexOffset(new_pg->data, n);
662
663 for(i = 0; i < n; i++)
664 {
665 key_data = start = BTREE_KeyData(pg, pg->n - n + i);
666 key_len = uncompress2(&key_data);
667
668 memcpy(p, start, (key_data - start) + key_len + SizeInt32);
669 tmp = p - new_pg->data;
670 p += (key_data - start) + key_len + SizeInt32;
671
672 *(BTREE_KeyIndexOffset(new_pg->data,i)) = (unsigned char)((tmp & 0xff00) >>8);
673 *(BTREE_KeyIndexOffset(new_pg->data,i) + 1) = (unsigned char) (tmp & 0xff);
674 }
675
676 new_pg->n = n;
677 new_pg->data_end = p - new_pg->data;
678
679 pg->n -= n;
680 p = BTREE_KeyIndexOffset(pg->data, pg->n);
681 for(i = 0; i < (int)pg->n ; i++)
682 {
683 key_data = start = BTREE_KeyData(pg,i);
684 key_len = uncompress2(&key_data);
685
686 memmove(p, start, (key_data - start) + key_len + SizeInt32);
687 tmp = p - pg->data;
688 p += (key_data - start) + key_len + SizeInt32;
689
690 *(BTREE_KeyIndexOffset(pg->data,i)) = (unsigned char)((tmp & 0xff00) >>8);
691 *(BTREE_KeyIndexOffset(pg->data,i) + 1) = (unsigned char) (tmp & 0xff);
692 }
693 pg->data_end = p - pg->data;;
694
695 return new_pg;
696 }
697
698
699 int BTREE_InsertInPage(BTREE *b, BTREE_Page *pg, unsigned char *key, int key_len, unsigned long data_pointer, int level, int update)
700 {
701 BTREE_Page *new_pg, *next_pg, *root_page, *father_pg, *tmp_pg;
702 unsigned int free_space, required_space;
703 int key_pos, key_len0;
704 unsigned char *key_data0;
705 int comp;
706
707 required_space = MAXINTCOMPSIZE + key_len + SizeInt32;
708
709 /* Check for Duplicate key if we are in a leaf page */
710 key_pos = BTREE_GetPositionForKey(pg, key, key_len, &comp);
711
712 if(comp == 0 && (pg->flags & BTREE_LEAF_NODE))
713 {
714 BTREE_FreePage(b, pg); /* Dup Key */
715 return -1;
716 }
717
718 free_space = pg->size - pg->data_end;
719 if(required_space <= free_space)
720 {
721 if (comp > 0)
722 key_pos++;
723 else if(comp == 0 && (pg->flags & BTREE_LEAF_NODE))
724 {
725 BTREE_FreePage(b, pg); /* Dup Key */
726 return -1;
727 }
728
729 if(!(pg->flags & BTREE_LEAF_NODE) && update)
730 {
731 BTREE_DelKeyInPage(pg, key_pos);
732 }
733
734 BTREE_AddKeyToPage(pg, key_pos, key, key_len, data_pointer);
735
736 if(key_pos == 0)
737 {
738
739 if(!(pg->flags & BTREE_ROOT_NODE))
740 {
741 key_data0 = BTREE_KeyData(pg,0);
742 key_len0 = uncompress2(&key_data0);
743 father_pg = BTREE_ReadPage(b,b->tree[level]);
744 BTREE_InsertInPage(b,father_pg, key_data0, key_len0, pg->page_number, level - 1, 1);
745 }
746 }
747 BTREE_WritePage(b, pg);
748 BTREE_FreePage(b, pg);
749 return 0;
750 }
751
752 /* There is not enough free space - Split page */
753 new_pg = BTREE_SplitPage(b, pg);
754 if(pg->next)
755 {
756 next_pg = BTREE_ReadPage(b, pg->next);
757 next_pg->prev = new_pg->page_number;
758 BTREE_WritePage(b, next_pg);
759 BTREE_FreePage(b, next_pg);
760 }
761 new_pg->next = pg->next;
762 new_pg->prev = pg->page_number;
763 pg->next = new_pg->page_number;
764
765 key_data0 = BTREE_KeyData(new_pg,0);
766 key_len0 = uncompress2(&key_data0);
767
768 /* Let's see where to put the key */
769 if(BTREE_CompareKeys(key, key_len, key_data0, key_len0) > 0)
770 {
771 tmp_pg = new_pg;
772 }
773 else
774 {
775 tmp_pg = pg;
776 }
777
778 key_pos = BTREE_GetPositionForKey(tmp_pg, key, key_len, &comp);
779 if(comp>0)
780 key_pos++;
781
782 if(!(tmp_pg->flags & BTREE_LEAF_NODE) && update)
783 {
784 BTREE_DelKeyInPage(tmp_pg, key_pos);
785 }
786 BTREE_AddKeyToPage(tmp_pg, key_pos, key, key_len, data_pointer);
787
788 if(pg->flags & BTREE_ROOT_NODE)
789 {
790 pg->flags &= ~BTREE_ROOT_NODE;
791 new_pg->flags &= ~BTREE_ROOT_NODE;
792 root_page = BTREE_NewPage(b,b->page_size, BTREE_ROOT_NODE);
793
794 key_data0 = BTREE_KeyData(pg,0);
795 key_len0 = uncompress2(&key_data0);
796 BTREE_AddKeyToPage(root_page, 0, key_data0, key_len0 , pg->page_number);
797
798 key_data0 = BTREE_KeyData(new_pg,0);
799 key_len0 = uncompress2(&key_data0);
800 BTREE_AddKeyToPage(root_page, 1, key_data0, key_len0, new_pg->page_number);
801
802 b->root_page = root_page->page_number;
803 BTREE_WritePage(b, pg);
804 BTREE_FreePage(b, pg);
805 BTREE_WritePage(b, new_pg);
806 BTREE_FreePage(b, new_pg);
807 BTREE_WritePage(b, root_page);
808 BTREE_FreePage(b, root_page);
809
810 return 0;
811 }
812
813 if(key_pos == 0 && tmp_pg == pg)
814 {
815 if(!(pg->flags & BTREE_ROOT_NODE))
816 {
817 father_pg = BTREE_ReadPage(b,b->tree[level]);
818 BTREE_InsertInPage(b,father_pg, key, key_len, pg->page_number, level - 1, 1);
819 }
820
821 BTREE_WritePage(b, pg);
822 BTREE_FreePage(b, pg);
823
824 key_data0 = BTREE_KeyData(new_pg,0);
825 key_len0 = uncompress2(&key_data0);
826 BTREE_FreePage(b, BTREE_Walk(b,key_data0,key_len0));
827 }
828 else
829 {
830 BTREE_WritePage(b, pg);
831 BTREE_FreePage(b, pg);
832
833 key_data0 = BTREE_KeyData(new_pg,0);
834 key_len0 = uncompress2(&key_data0);
835 }
836
837 father_pg = BTREE_ReadPage(b,b->tree[level]);
838 BTREE_InsertInPage(b,father_pg, key_data0, key_len0, new_pg->page_number, level - 1, 0);
839
840
841 BTREE_WritePage(b, new_pg);
842 BTREE_FreePage(b, new_pg);
843
844 return 0;
845 }
846
847
848 int BTREE_Insert(BTREE *b, unsigned char *key, int key_len, unsigned long data_pointer)
849 {
850 BTREE_Page *pg = BTREE_Walk(b,key,key_len);
851 return BTREE_InsertInPage(b, pg, key, key_len, data_pointer, b->levels - 1, 0);
852 }
853
854 int BTREE_Update(BTREE *b, unsigned char *key, int key_len, unsigned long new_data_pointer)
855 {
856 int comp, k, key_len_k;
857 unsigned char *key_k;
858 BTREE_Page *pg = BTREE_Walk(b,key,key_len);
859
860
861 /* Pack pointer */
862 new_data_pointer = PACKLONG(new_data_pointer);
863
864 /* Get key position */
865 k = BTREE_GetPositionForKey(pg, key, key_len, &comp);
866
867 if(comp)
868 {
869 return -1; /*Key not found */
870 }
871
872 key_k = BTREE_KeyData(pg,k);
873
874 key_len_k = uncompress2(&key_k);
875
876 if ( key_len_k != key_len)
877 return -1; /* Error - Should never happen */
878
879 key_k += key_len_k;
880
881 memcpy(key_k, &new_data_pointer, SizeInt32);
882
883 BTREE_WritePage(b, pg);
884 BTREE_FreePage(b, pg);
885
886 return 0;
887 }
888
889
890 long BTREE_Search(BTREE *b, unsigned char *key, int key_len, unsigned char **found, int *found_len, int exact_match)
891 {
892 BTREE_Page *pg = BTREE_ReadPage(b, b->root_page);
893 unsigned int i = 0;
894 unsigned long next_page;
895 unsigned char *key_k;
896 unsigned int key_len_k;
897 unsigned long father_page;
898 unsigned long data_pointer;
899
900 b->tree[i++] = 0; /* No father for root */
901
902 father_page = pg->page_number;
903 while(!(pg->flags & BTREE_LEAF_NODE))
904 {
905 next_page = BTREE_GetKeyFromPage(b, pg, key, key_len, &key_k, &key_len_k);
906 BTREE_FreePage(b, pg);
907 pg = BTREE_ReadPage(b, next_page);
908 b->tree[i++] = father_page;
909 father_page = pg->page_number;
910 }
911 b->levels = i;
912 data_pointer = BTREE_GetKeyFromPage(b, pg, key, key_len, &key_k, &key_len_k);
913
914 if(exact_match)
915 {
916 if(BTREE_CompareKeys(key,key_len,key_k,key_len_k)!=0)
917 return -1L;
918 }
919
920 *found_len = key_len_k;
921 *found = emalloc(key_len_k);
922 memcpy(*found,key_k,key_len_k);
923
924 BTREE_FreePage(b,pg);
925 return data_pointer;
926 }
927
928 long BTREE_Next(BTREE *b, unsigned char **found, int *found_len)
929 {
930 BTREE_Page *pg = BTREE_ReadPage(b, b->current_page);
931 unsigned long next_page;
932 long data_pointer;
933 unsigned char *key_k;
934 int key_len_k;
935 b->current_position++;
936 if(pg->n == b->current_position)
937 {
938 next_page = pg->next;
939 BTREE_FreePage(b,pg);
940 if(!next_page)
941 return -1;
942 pg = BTREE_ReadPage(b, next_page);
943 b->current_page = next_page;
944 b->current_position = 0;
945 }
946 key_k = BTREE_KeyData(pg,b->current_position);
947 *found_len = key_len_k = uncompress2(&key_k);
948 *found = emalloc(key_len_k);
949 memcpy(*found,key_k,key_len_k);
950 data_pointer = UNPACKLONG(*(unsigned long *) (key_k + key_len_k));
951
952 BTREE_FreePage(b,pg);
953
954 return data_pointer;
955 }
956
957 #ifdef DEBUG
958
959 #include <time.h>
960
961 #define N_TEST 300000
962
963 #define F_READ_BINARY "rb"
964 #define F_WRITE_BINARY "wb"
965 #define F_READWRITE_BINARY "rb+"
966
967 #define F_READ_TEXT "r"
968 #define F_WRITE_TEXT "w"
969 #define F_READWRITE_TEXT "r+"
970
971 int main()
972 {
973 FILE *fp;
974 BTREE *bt;
975 unsigned char buffer[20];
976 int i;
977 static int nums[N_TEST];
978 unsigned long root_page;
979 unsigned char *found;
980 int found_len;
981 srand(time(NULL));
982
983 goto test2;
984
985 fp = fopen("kkkkk",F_WRITE_BINARY);
986 fwrite("asjhd",1,5,fp);
987 fclose(fp);
988 fp = fopen("kkkkk",F_READWRITE_BINARY);
989
990 printf("\n\nIndexing\n\n");
991
992 bt = BTREE_Create(fp, 15);
993 for(i=N_TEST - 1;i>=0;i--)
994 {
995 // nums[i] = rand();
996 nums[i]=i;
997
998
999 sprintf(buffer,"%d",nums[i]);
1000 // sprintf(buffer,"%.12d",nums[i]);
1001 BTREE_Insert(bt,buffer,strlen(buffer),nums[i]);
1002 if(nums[i]!= BTREE_Search(bt,buffer,strlen(buffer),&found,&found_len,1))
1003 printf("\n\nmal %s\n\n",buffer);
1004 if(!(i%1000))
1005 {
1006 BTREE_FlushCache(bt);
1007 printf("%d \r",i);
1008 }
1009 }
1010
1011 root_page = BTREE_Close(bt);
1012 fclose(fp);
1013
1014 search:;
1015 printf("\n\nSearching\n\n");
1016
1017 fp = fopen("kkkkk",F_READ_BINARY);
1018 bt = BTREE_Open(fp,15,root_page);
1019
1020 for(i=0;i<N_TEST;i++)
1021 {
1022 sprintf(buffer,"%d",nums[i]);
1023 // sprintf(buffer,"%.12d",nums[i]);
1024
1025 if(nums[i] != BTREE_Search(bt,buffer,strlen(buffer),&found,&found_len,1))
1026 printf("\n\nmal %s\n\n",buffer);
1027 if(!(i%1000))
1028 printf("%d \r",i);
1029 }
1030
1031 fclose(fp);
1032
1033 test2:;
1034
1035
1036 fp = fopen("kkkkk",F_WRITE_BINARY);
1037 fclose(fp);
1038 fp = fopen("kkkkk",F_READWRITE_BINARY);
1039
1040 fwrite("aaa",1,3,fp);
1041
1042 printf("\n\nIndexing\n\n");
1043
1044 bt = BTREE_Create(fp, 15);
1045 for(i=0;i<N_TEST;i++)
1046 {
1047 // nums[i] = rand();
1048 nums[i]=i;
1049 sprintf(buffer,"%d",nums[i]);
1050 // sprintf(buffer,"%.12d",nums[i]);
1051 BTREE_Insert(bt,buffer,strlen(buffer),nums[i]);
1052 if(nums[i]!= BTREE_Search(bt,buffer,strlen(buffer),&found,&found_len,1))
1053 printf("\n\nmal %s\n\n",buffer);
1054 if(!(i%1000))
1055 {
1056 BTREE_FlushCache(bt);
1057 printf("%d \r",i);
1058 }
1059 }
1060
1061 root_page = BTREE_Close(bt);
1062 fclose(fp);
1063
1064 printf("\n\nSearching\n\n");
1065
1066 fp = fopen("kkkkk",F_READ_BINARY);
1067 bt = BTREE_Open(fp,15,root_page);
1068
1069 for(i=0;i<N_TEST;i++)
1070 {
1071 sprintf(buffer,"%d",nums[i]);
1072 if(nums[i] != BTREE_Search(bt,buffer,strlen(buffer),&found,&found_len,1))
1073 printf("\n\nmal %s\n\n",buffer);
1074 if(!(i%1000))
1075 printf("%d \r",i);
1076 }
1077
1078
1079 fclose(fp);
1080 }
1081
1082 #endif

  ViewVC Help
Powered by ViewVC 1.1.22