You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: _parts/part4.md
+1-1Lines changed: 1 addition & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -299,7 +299,7 @@ end
299
299
continue;
300
300
```
301
301
302
-
Alright, that's enough testing for now. Next is a very important feature: persistance! We're going to save our database to a file and read it back out again.
302
+
Alright, that's enough testing for now. Next is a very important feature: persistence! We're going to save our database to a file and read it back out again.
Copy file name to clipboardExpand all lines: _parts/part5.md
+6-6Lines changed: 6 additions & 6 deletions
Original file line number
Diff line number
Diff line change
@@ -31,7 +31,7 @@ end
31
31
32
32
Like sqlite, we're going to persist records by saving the entire database to a file.
33
33
34
-
We already set ourselves up to do that by serializing rows into page-sized memory blocks. To add persistance, we can simply write those blocks of memory to a file, and read them back into memory the next time the program starts up.
34
+
We already set ourselves up to do that by serializing rows into page-sized memory blocks. To add persistence, we can simply write those blocks of memory to a file, and read them back into memory the next time the program starts up.
35
35
36
36
To make this easier, we're going to make an abstraction called the pager. We ask the pager for page number `x`, and the pager gives us back a block of memory. It first looks in its cache. On a cache miss, it copies data from disk into memory (by reading the database file).
37
37
@@ -255,7 +255,7 @@ Lastly, we need to accept the filename as a command-line argument:
255
255
+ Table* table = db_open(filename);
256
256
+
257
257
```
258
-
With these changes, we're able to close then reopen the database, and our records are stil there!
258
+
With these changes, we're able to close then reopen the database, and our records are still there!
259
259
260
260
```
261
261
~ ./db mydb.db
@@ -274,23 +274,23 @@ db > .exit
274
274
~
275
275
```
276
276
277
-
For extra fun, let's take a look at `mydb.db` to see how our data is being stored. I'll use vim as a hex editior to look at the memory layout of the file:
277
+
For extra fun, let's take a look at `mydb.db` to see how our data is being stored. I'll use vim as a hex editor to look at the memory layout of the file:
278
278
279
279
```
280
280
vim mydb.db
281
281
:%!xxd
282
282
```
283
283
{% include image.html url="assets/images/file-format.png" description="Current File Format" %}
284
284
285
-
The first four bytes are the id of the first row (4 bytes because we store a uint32_t). It's stored in little-endian byte order, so the least signifigant byte comes first (01), followed by the higher-order bytes (00 00 00). We used `memcpy()` to copy bytes from our `Row` struct into the page cache, so that means the struct was laid out in memory in little-endian byte order. That's an attribute of the machine I compiled the program for. If we wanted to write a database file on my machine, then read it on a big-endian machine, we'd have to change our `serialize_row()` and `deserialize_row()` methods to always store and read bytes in the same order.
285
+
The first four bytes are the id of the first row (4 bytes because we store a uint32_t). It's stored in little-endian byte order, so the least significant byte comes first (01), followed by the higher-order bytes (00 00 00). We used `memcpy()` to copy bytes from our `Row` struct into the page cache, so that means the struct was laid out in memory in little-endian byte order. That's an attribute of the machine I compiled the program for. If we wanted to write a database file on my machine, then read it on a big-endian machine, we'd have to change our `serialize_row()` and `deserialize_row()` methods to always store and read bytes in the same order.
286
286
287
-
The next 33 bytes store the username as a null-terminated string. Apparently "cstack" in ASCII hexidecimal is `63 73 74 61 63 6b`, followed by a null character (`00`). The rest of the 33 bytes are unused.
287
+
The next 33 bytes store the username as a null-terminated string. Apparently "cstack" in ASCII hexadecimal is `63 73 74 61 63 6b`, followed by a null character (`00`). The rest of the 33 bytes are unused.
288
288
289
289
The next 256 bytes store the email in the same way. Here we can see some random junk after the terminating null character. This is most likely due to uninitialized memory in our `Row` struct. We copy the entire 256-byte email buffer into the file, including any bytes after the end of the string. Whatever was in memory when we allocated that struct is still there. But since we use a terminating null character, it has no effect on behavior.
290
290
291
291
## Conclusion
292
292
293
-
Alright! We've got persistence. It's not the greatest. For example if you kill the program without typing `.exit`, you lose your changes. Additionallly, we're writing all pages back to disk, even pages that haven't changed since we read them from disk. These are issues we can address later. The next thing I think we should work on is implementing the B-tree.
293
+
Alright! We've got persistence. It's not the greatest. For example if you kill the program without typing `.exit`, you lose your changes. Additionally, we're writing all pages back to disk, even pages that haven't changed since we read them from disk. These are issues we can address later. The next thing I think we should work on is implementing the B-tree.
0 commit comments