Implementation of a simple database----APUE Chapter a library

Source: Internet
Author: User
Tags goto readable

A Database Library

I will say tomorrow 10 o'clock in the morning test database, I am still writing blog ... What mentality Qaq


I still can't help but spit groove, the database of the class .... (15,000 words are omitted here)

--------------------------------------------------------------------------------------------------------------- -


Business... Before has been shelved Apue's later chapters, tomorrow Test database, today whim, anyway Apue provides a way to achieve a data,

Perhaps we should write a database ourselves. Hum ╭ (╯^╰) ╮ is so proud of the charming ~

My name is all right, the name of the database is called ... jasper.


Disclaimer : This database is not my original (K-God works, I completely ... Not an order of magnitude), I will make a slight change to it ...

Put the results first, interested in watching, you can discuss with me, [email protected], no interest, browser click X.


It was supposed to be a very formal mature database, a shell out of the sense of the interface string Syntax command analysis a bit * *

So, just make up the concept first-want to test or use the "toy" database, need a certain C language Foundation, and then call to provide a good API.


To be able to manipulate the database, we have to write a simple calling program ~

#include "apue_db.h" #include <stdio.h> #include <fcntl.h> #define STRING_SZ 100#define data_set 3int main () { Char STR_KEY[DATA_SET][STRING_SZ] = {{"Alpha"}, {"Belta"}, {"Gama"}};char STR_DAT[DATA_SET][STRING_SZ ] = {{"data1"}, {"Data2"}, {"Data3"}};D Bhandle handler = Db_open ("./database", O_creat | O_trunc | O_rdwr, File_mode); if (Db_store (handler,str_key[0],str_dat[0],db_insert)! = 0) {printf ("error!      Db_store failed in function%s\n ", __function__);p rintf (" Trying to store key:%s\t data:%s\n ", Str_key[0],str_dat[0]); Goto failed;} if (Db_store (handler,str_key[1],str_dat[1],db_insert)! = 0) {printf ("error!      Db_store failed in function%s\n ", __function__);p rintf (" Trying to store key:%s\t data:%s\n ", STR_KEY[1],STR_DAT[1]); Goto failed;} if (Db_store (handler,str_key[2],str_dat[2],db_insert)! = 0) {printf ("error!                            Db_store failed in function%s\n ",__function__);p rintf ("Trying to store key:%s\t data:%s\n", str_key[2],str_dat[2]); Goto failed;} Failed:db_close (handler); return 0;}


Obviously, we want to use Db_store to store the data in Str_dat based on Str_key.




The data is stored in Database.dat and indexed using DATABASE.IDX.


Of course, I'd like to see my nagging people who want to see how it's going to come true ...

the split line has been specially cut out. The following are mainly personal ideas, or meet the personal feel may be difficult place. is not "about how to get this database done". RTFSC:)


There is any viewer interested in this data, hoping to communicate via email [email protected]

Don ' t panic

--------------------------------------------------------------------------------------------------------------- ----

If you feel that the code style is not the same as the taste, you can try it, go to GitHub to get my own source of re-writing

If you don't know it, just look at the notes on the book.

Https://github.com/jasonleaster/APUE_study_source_code/tree/liu/chapter_20



Design of the database:

This simple database is comprised of two files----index file & data file.

An index file, a data file. Enables the separation of indexed and stored data. In my personal view, this is nothing more than a clear view of the architecture.

Imagine, with a file to express the database, it will be very "messy", lengthy, miscellaneous. Think so? :) have to admire the ideas of these designers.


Figure 1


The most important thing to emphasize is that when we store an address pointer, you see all the identifiers about PTR in the diagram.

Their storage format is ASCII code! Repeatedly stressed, otherwise look at the code will look at crying.

This is a great highlight of database design, because the data of the database may be used in different systems, different hardware platforms, due to the way the system represents the data (size end, pointer length, etc.), and the data may be inconsistent. At this point, there is a way to express the ASCII code directly, as a string exists.

For example, address 0x0010 directly with "16" to represent and store. It's pretty cool .


The designer assumes that the maximum length of the pointer is a decimal 6-digit number.


Figure 2

The 999999 = = 10^ (PTR_SZ)-1


The following APIs are defined for what the database can do. (Then I will write a similar to the shell of the east, so that the control of the database syntax like the MySQL syntax, certainly will not be fully implement the MySQL syntax, but it will be very naive very interesting, so that the minimum simple database implementation principle is clear, the special kill paper tiger).


Figure 3


The entire database is abstracted using the struct db. All of our APIs, however, revolve around this object and manipulate the database in a variety of variations.

We have written all the things that can be used to describe a database in this structure, and the essence of this idea is oo.

/* Library ' s private representation of the database.  */typedef struct {int idxfd;  /* FD for index file */int datfd; /* FD for data file */char *idxbuf; /* malloc ' ed buffer for index record */char *datbuf;   /* malloc ' ed buffer for data record*/char *name; /* Name DB was opened under */off_t Idxoff; /* Offset in index file of index record */* * key is at (Idxoff + PTR_SZ + IDXLEN_SZ) */size_t Idxlen; /* Length of index record */* excludes IDXLEN_SZ bytes at front of record */* includes newline at end of IND Ex record */off_t Datoff; /* Offset in data file of data record */size_t Datlen; /* Length of data record */* includes newline at end */off_t ptrval; /* Contents of chain PTR in index record */off_t Ptroff; /* Chain PTR offset pointing to this IDX record */off_t Chainoff;  /* Offset of hash chain for this index record */off_t Hashoff;    /* Offset in index file of hash table */Dbhash Nhash; /* Current Hash tableSize */COUNT Cnt_delok;   /* Delete OK */COUNT Cnt_delerr;  /* Delete error */COUNT Cnt_fetchok; /* Fetch OK */COUNT Cnt_fetcherr;  /* Fetch error */COUNT Cnt_nextrec;    /* Nextrec */COUNT Cnt_stor1;    /* Store:db_insert, no empty, appended */COUNT Cnt_stor2;    /* Store:db_insert, found empty, reused */COUNT Cnt_stor3;    /* Store:db_replace, diff len, appended */COUNT Cnt_stor4;  /* Store:db_replace, same len, overwrote */COUNT Cnt_storerr; /* Store error */} DB;


Before Figure 3 defines a lot of APIs that operate in db, let's look at the implementations of these APIs.

The following functions have been implemented since the API implementation of Figure 3 above. A profound understanding of what is called interface and implementation of the separation ... I'm going to do it later.


Figure 4


The code is close to 10^3 so don't pull it out. Record what I think is the key part.

db_open (const char *pathname, int oflag, ...)


Figure 5

Calculates the string length of the file name (excluding NUL) based on the file name provided by pathname

And then passed to _db_alloc (len), this _db_alloc will actually return a db struct associated with our file name pathname character.



Figure 6

Here we get the initial database, start initializing it, determine the good hash table in the index file start position (Hash_off 6) and hash table total size (nhash_def 137), here 6 is the front PTR_SZ, This means that the first 6 bytes of the index file are empty.

, each hash unit is PTR_SZ size, altogether has nhash_def. The 6bybe in front of the empty is intentional, used to record a pointer (denoted by a string). This pointer usage is very special, can be understood later, called the Free list pointer (this guy has been tossing me for a long time).


_db_alloc

Will notice here that malloc has a difference of + 5, 2, 2. This is because the db->name time to consider our database file naming method, to add. dat

So here ". Dat" is 5 char. And then the next two +2 is to take into account the string input when we will have \ n and NUL.

This ensures that we define the rigor of Idxlen_max and Datlen_max!


Figure 7

Db_close and _db_free () feel very simple, just a little bit at the time of Apue author's realization. Slightly.. Not secure.

The pointer to the API parameter is not null-detected.


Figure 8

If the DB is null, I'll kneel down and steady.



Db_fetch ()

This function is used to find out whether the item data is already in the database based on key.

Nothing to emphasize, this is an interface, successfully found the corresponding data, OK. That returns a pointer to PTR ,

This pointer points to the data you want to find (point to the database file)


The core of the interface is _find_and_lock ()



_find_and_lock ()

Calculates the hash value according to the string that the key points to, then determines the entry of the hash table and attempts to find the corresponding item.

The third parameter, Writelock, is designed to provide a preemption problem that prevents concurrency.

The Read_lock guarantee is readable and not writable, and the write_lock is neither readable nor writable.



Figure 9

As seen above, the Db->chainoff is obtained by adding the initial offset of the hash table.

According to Chianoff through the _db_readptr to find the hash table corresponding location data, this data is the index of the address tag.

If this address is 0, while the loop does not go in, and finally returns-1, indicating that _find_and_lock failed, that is, according to the parameter key, there is no corresponding data.

If offset is nonzero, it means that we may have found the corresponding data.

Only the real one is the same as the key, not the simple hash value. To determine if the corresponding data was found.

If found, then break jumps out of the while loop and returns 0. We are prompted to find this guy.

If the one-way list along the hash Chian has not been found, we will encounter _db_readidx return 0, prompting _find_and_lock to fail.


Figure 10

It is worth noting that figure 10 will have a call to _db_readidx ()

This function updates the file bias of the data file, which is Db->datoff.



Postscript:

Would have thought that a day can be done, the tardiness of two days of this thing ...





In a classroom trying hard to pass the empty scene and black and white dull, the performance of contemporary college students confused, no and confused










Implementation of a simple database----APUE Chapter a library

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.