-
Notifications
You must be signed in to change notification settings - Fork 1
/
table.h
121 lines (109 loc) · 3.18 KB
/
table.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "types.h"
#include "pager.h"
// #include "cursor.h"
#include "btree.h"
#ifndef TABLE_H
#define TABLE_H
void serialize_row(row_t *source, void *dest)
{
memcpy(dest + ID_OFFSET, &(source->id), ID_SIZE);
memcpy(dest + USERNAME_OFFSET, &(source->username), USERNAME_SIZE);
memcpy(dest + EMAIL_OFFSET, &(source->email), EMAIL_SIZE);
}
void deserialize_row(void *source, row_t *dest)
{
memcpy(&(dest->id), source + ID_OFFSET, ID_SIZE);
memcpy(&(dest->username), source + USERNAME_OFFSET, USERNAME_SIZE);
memcpy(&(dest->email), source + EMAIL_OFFSET, EMAIL_SIZE);
}
void print_row(row_t *row)
{
printf("(%d, %s, %s)\n", row->id, row->username, row->email);
}
// opening the database file
// initializing a pager data structure
// initializing a table data structure
table_t *db_open(const char *filename)
{
pager_t *pager = pager_open(filename);
table_t *table = (table_t *)malloc(sizeof(table_t));
table->pager = pager;
table->root_page_num = 0;
if (pager->num_pages == 0)
{
// New database file. Initialize page 0 as leaf node.
void *root_node = get_page(pager, 0);
init_leaf_node(root_node);
set_node_root(root_node, true);
}
return table;
}
// flushes the page cache to disk
// closes the database file
// frees the memory for the Pager and Table data structures
void db_close(table_t *table)
{
pager_t *pager = table->pager;
for (uint32_t i = 0; i < pager->num_pages; i++)
{
if (pager->pages[i] == NULL)
continue;
pager_flush(pager, i);
free(pager->pages[i]);
pager->pages[i] = NULL;
}
// There may be a partial page to write to the end of the file
// This should not be needed after we switch to a B-tree
// uint32_t num_additional_rows = table->num_rows % ROWS_PER_PAGE;
// if (num_additional_rows > 0)
// {
// uint32_t page_num = num_full_pages;
// if (pager->pages[page_num] != NULL)
// {
// pager_flush(pager, page_num, num_additional_rows * ROW_SIZE);
// free(pager->pages[page_num]);
// pager->pages[page_num] = NULL;
// }
// }
int ret = close(pager->file_descriptor);
if (ret < 0)
{
printf("Error closing db file.\n");
exit(EXIT_FAILURE);
}
for (uint32_t i = 0; i < TABLE_MAX_PAGES; i++)
{
if (pager->pages[i] != NULL)
{
free(pager->pages[i]);
pager->pages[i] = NULL;
}
}
free(pager);
free(table);
}
/**
* Return the position of the given key.
* If the key is not present, return the position
* where it should be inserted
**/
cursor_t *table_find(table_t *table, uint32_t key)
{
uint32_t root_page_num = table->root_page_num;
void *root_node = get_page(table->pager, root_page_num);
if (get_node_type(root_node) == NODE_LEAF)
{
return leaf_node_find(table, root_page_num, key);
}
else
{
// printf("Need to implement searching an internal node\n");
// exit(EXIT_FAILURE);
return internal_node_find(table, root_page_num, key);
}
}
#endif