⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 00000016.htm

📁 一份很好的linux入门资料
💻 HTM
📖 第 1 页 / 共 5 页
字号:
&nbsp;DB&nbsp;&nbsp;*db;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;/*&nbsp;Use&nbsp;calloc,&nbsp;to&nbsp;init&nbsp;structure&nbsp;to&nbsp;zero&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;if&nbsp;(&nbsp;(db&nbsp;=&nbsp;calloc(1,&nbsp;sizeof(DB)))&nbsp;==&nbsp;NULL)&nbsp;&nbsp;<BR>&nbsp;&nbsp;err_dump(&quot;calloc&nbsp;error&nbsp;for&nbsp;DB&quot;);&nbsp;&nbsp;<BR>&nbsp;db-&gt;idxfd&nbsp;=&nbsp;db-&gt;datfd&nbsp;=&nbsp;-1;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;descriptors&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;&nbsp;/*&nbsp;Allocate&nbsp;room&nbsp;for&nbsp;the&nbsp;name.&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+5&nbsp;for&nbsp;&quot;.idx&quot;&nbsp;or&nbsp;&quot;.dat&quot;&nbsp;plus&nbsp;null&nbsp;at&nbsp;end.&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;if&nbsp;(&nbsp;(db-&gt;name&nbsp;=&nbsp;malloc(namelen&nbsp;+&nbsp;5))&nbsp;==&nbsp;NULL)&nbsp;&nbsp;<BR>&nbsp;&nbsp;err_dump(&quot;malloc&nbsp;error&nbsp;for&nbsp;name&quot;);&nbsp;&nbsp;<BR>&nbsp;&nbsp;/*&nbsp;Allocate&nbsp;an&nbsp;index&nbsp;buffer&nbsp;and&nbsp;a&nbsp;data&nbsp;buffer.&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+2&nbsp;for&nbsp;newline&nbsp;and&nbsp;null&nbsp;at&nbsp;end.&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;if&nbsp;(&nbsp;(db-&gt;idxbuf&nbsp;=&nbsp;malloc(IDXLEN_MAX&nbsp;+&nbsp;2))&nbsp;==&nbsp;NULL)&nbsp;&nbsp;<BR>&nbsp;&nbsp;err_dump(&quot;malloc&nbsp;error&nbsp;for&nbsp;index&nbsp;buffer&quot;);&nbsp;&nbsp;<BR>&nbsp;if&nbsp;(&nbsp;(db-&gt;datbuf&nbsp;=&nbsp;malloc(DATLEN_MAX&nbsp;+&nbsp;2))&nbsp;==&nbsp;NULL)&nbsp;&nbsp;<BR>&nbsp;&nbsp;err_dump(&quot;malloc&nbsp;error&nbsp;for&nbsp;data&nbsp;buffer&quot;);&nbsp;&nbsp;<BR>&nbsp;return(db);&nbsp;&nbsp;<BR>}&nbsp;&nbsp;<BR>程序16.4&nbsp;_db_alloc函数&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;索引缓冲和数据缓冲的大小在db.h中定义。我们的数据库函数库可以通过让这&nbsp;&nbsp;<BR>些缓冲按需要动态扩张来得到加强。其方法可以是记录这两个缓冲的大小,然后在&nbsp;&nbsp;<BR>需要更大的缓冲时调用realloc。&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;在函数_db_free(程序16.5)中,这些缓冲将被释放,同时打开的文件被关闭&nbsp;&nbsp;<BR>。db_open在打开索引文件和数据文件时如果遇到错误,则调用_db_free释放资源&nbsp;&nbsp;<BR>。db_close(程序16.6)也调用_db_free。&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;函数db_fetch(程序16.7)根据给定的主键来读取一条记录。它调用_db_fin&nbsp;&nbsp;<BR>d在数据库中查找一条索引记录,如果找到,再调用_db_readdat来读取对应的数据&nbsp;&nbsp;<BR>记录。&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>#include&nbsp;&quot;db.h&quot;&nbsp;&nbsp;<BR>/*&nbsp;Free&nbsp;up&nbsp;a&nbsp;DB&nbsp;structure,&nbsp;and&nbsp;all&nbsp;the&nbsp;malloc'ed&nbsp;buffers&nbsp;it&nbsp;&nbsp;<BR>&nbsp;*&nbsp;may&nbsp;point&nbsp;to.&nbsp;&nbsp;Also&nbsp;close&nbsp;the&nbsp;file&nbsp;descriptors&nbsp;if&nbsp;still&nbsp;open.&nbsp;*/&nbsp;&nbsp;<BR>int&nbsp;&nbsp;<BR>_db_free(DB&nbsp;*db)&nbsp;&nbsp;<BR>{&nbsp;&nbsp;<BR>&nbsp;if&nbsp;(db-&gt;idxfd&nbsp;&gt;=&nbsp;0&nbsp;&amp;&amp;&nbsp;close(db-&gt;idxfd)&nbsp;&lt;&nbsp;0)&nbsp;&nbsp;<BR>&nbsp;&nbsp;err_dump(&quot;index&nbsp;close&nbsp;error&quot;);&nbsp;&nbsp;<BR>&nbsp;if&nbsp;(db-&gt;datfd&nbsp;&gt;=&nbsp;0&nbsp;&amp;&amp;&nbsp;close(db-&gt;datfd)&nbsp;&lt;&nbsp;0)&nbsp;&nbsp;<BR>&nbsp;&nbsp;err_dump(&quot;data&nbsp;close&nbsp;error&quot;);&nbsp;&nbsp;<BR>&nbsp;db-&gt;idxfd&nbsp;=&nbsp;db-&gt;datfd&nbsp;=&nbsp;-1;&nbsp;&nbsp;<BR>&nbsp;if&nbsp;(db-&gt;idxbuf&nbsp;!=&nbsp;NULL)&nbsp;&nbsp;<BR>&nbsp;&nbsp;free(db-&gt;idxbuf);&nbsp;&nbsp;<BR>&nbsp;if&nbsp;(db-&gt;datbuf&nbsp;!=&nbsp;NULL)&nbsp;&nbsp;<BR>&nbsp;&nbsp;free(db-&gt;datbuf);&nbsp;&nbsp;<BR>&nbsp;if&nbsp;(db-&gt;name&nbsp;!=&nbsp;NULL)&nbsp;&nbsp;<BR>&nbsp;&nbsp;free(db-&gt;name);&nbsp;&nbsp;<BR>&nbsp;free(db);&nbsp;&nbsp;<BR>&nbsp;return(0);&nbsp;&nbsp;<BR>}&nbsp;&nbsp;<BR>程序16.5&nbsp;_db_free函数&nbsp;&nbsp;<BR>#include&nbsp;&quot;db.h&quot;&nbsp;&nbsp;<BR>void&nbsp;&nbsp;<BR>db_close(DB&nbsp;*db)&nbsp;&nbsp;<BR>{&nbsp;&nbsp;<BR>&nbsp;_db_free(db);&nbsp;/*&nbsp;closes&nbsp;fds,&nbsp;free&nbsp;buffers&nbsp;&amp;&nbsp;struct&nbsp;*/&nbsp;&nbsp;<BR>}&nbsp;&nbsp;<BR>程序16.6&nbsp;db_close函数&nbsp;&nbsp;<BR>#include&nbsp;&quot;db.h&quot;&nbsp;&nbsp;<BR>/*&nbsp;Fetch&nbsp;a&nbsp;specified&nbsp;record.&nbsp;&nbsp;<BR>&nbsp;*&nbsp;We&nbsp;return&nbsp;a&nbsp;pointer&nbsp;to&nbsp;the&nbsp;null-terminated&nbsp;data.&nbsp;*/&nbsp;&nbsp;<BR>char&nbsp;*&nbsp;&nbsp;<BR>db_fetch(DB&nbsp;*db,&nbsp;const&nbsp;char&nbsp;*key)&nbsp;&nbsp;<BR>{&nbsp;&nbsp;<BR>&nbsp;char&nbsp;*ptr;&nbsp;&nbsp;<BR>&nbsp;if&nbsp;(_db_find(db,&nbsp;key,&nbsp;0)&nbsp;&lt;&nbsp;0)&nbsp;{&nbsp;&nbsp;<BR>&nbsp;&nbsp;ptr&nbsp;=&nbsp;NULL;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;error,&nbsp;record&nbsp;not&nbsp;found&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;&nbsp;db-&gt;cnt_fetcherr++;&nbsp;&nbsp;<BR>&nbsp;}&nbsp;else&nbsp;{&nbsp;&nbsp;<BR>&nbsp;&nbsp;ptr&nbsp;=&nbsp;_db_readdat(db);&nbsp;/*&nbsp;return&nbsp;pointer&nbsp;to&nbsp;data&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;&nbsp;db-&gt;cnt_fetchok++;&nbsp;&nbsp;<BR>&nbsp;}&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;/*&nbsp;Unlock&nbsp;the&nbsp;hash&nbsp;chain&nbsp;that&nbsp;_db_find()&nbsp;locked&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;if&nbsp;(un_lock(db-&gt;idxfd,&nbsp;db-&gt;chainoff,&nbsp;SEEK_SET,&nbsp;1)&nbsp;&lt;&nbsp;0)&nbsp;&nbsp;<BR>&nbsp;&nbsp;err_dump(&quot;un_lock&nbsp;error&quot;);&nbsp;&nbsp;<BR>&nbsp;return(ptr);&nbsp;&nbsp;<BR>}&nbsp;&nbsp;<BR>程序16.7&nbsp;db_fetch函数&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;函数_db_find(程序16.8)通过遍历Hash链来查找记录。db_fetch,db_dele&nbsp;&nbsp;<BR>te和db_store这几个需要根据主键找记录的函数都调用它。&nbsp;&nbsp;<BR>#include&nbsp;&quot;db.h&quot;&nbsp;&nbsp;<BR>/*&nbsp;Find&nbsp;the&nbsp;specified&nbsp;record.&nbsp;&nbsp;<BR>&nbsp;*&nbsp;Called&nbsp;by&nbsp;db_delete(),&nbsp;db_fetch(),&nbsp;and&nbsp;db_store().&nbsp;*/&nbsp;&nbsp;<BR>int&nbsp;&nbsp;<BR>_db_find(DB&nbsp;*db,&nbsp;const&nbsp;char&nbsp;*key,&nbsp;int&nbsp;writelock)&nbsp;&nbsp;<BR>{&nbsp;&nbsp;<BR>&nbsp;off_t&nbsp;offset,&nbsp;nextoffset;&nbsp;&nbsp;<BR>&nbsp;&nbsp;/*&nbsp;Calculate&nbsp;hash&nbsp;value&nbsp;for&nbsp;this&nbsp;key,&nbsp;then&nbsp;calculate&nbsp;byte&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;offset&nbsp;of&nbsp;corresponding&nbsp;chain&nbsp;ptr&nbsp;in&nbsp;hash&nbsp;table.&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;This&nbsp;is&nbsp;where&nbsp;our&nbsp;search&nbsp;starts.&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;/*&nbsp;calc&nbsp;offset&nbsp;in&nbsp;hash&nbsp;table&nbsp;for&nbsp;this&nbsp;key&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;db-&gt;chainoff&nbsp;=&nbsp;(_db_hash(db,&nbsp;key)&nbsp;*&nbsp;PTR_SZ)&nbsp;+&nbsp;db-&gt;hashoff;&nbsp;&nbsp;<BR>&nbsp;db-&gt;ptroff&nbsp;=&nbsp;db-&gt;chainoff;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;/*&nbsp;Here's&nbsp;where&nbsp;we&nbsp;lock&nbsp;this&nbsp;hash&nbsp;chain.&nbsp;&nbsp;It's&nbsp;the&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;caller's&nbsp;responsibility&nbsp;to&nbsp;unlock&nbsp;it&nbsp;when&nbsp;done.&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Note&nbsp;we&nbsp;lock&nbsp;and&nbsp;unlock&nbsp;only&nbsp;the&nbsp;first&nbsp;byte.&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;if&nbsp;(writelock)&nbsp;{&nbsp;&nbsp;<BR>&nbsp;&nbsp;if&nbsp;(writew_lock(db-&gt;idxfd,&nbsp;db-&gt;chainoff,&nbsp;SEEK_SET,&nbsp;1)&nbsp;&lt;&nbsp;0)&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;err_dump(&quot;writew_lock&nbsp;error&quot;);&nbsp;&nbsp;<BR>&nbsp;}&nbsp;else&nbsp;{&nbsp;&nbsp;<BR>&nbsp;&nbsp;if&nbsp;(readw_lock(db-&gt;idxfd,&nbsp;db-&gt;chainoff,&nbsp;SEEK_SET,&nbsp;1)&nbsp;&lt;&nbsp;0)&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;err_dump(&quot;readw_lock&nbsp;error&quot;);&nbsp;&nbsp;<BR>&nbsp;}&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;/*&nbsp;Get&nbsp;the&nbsp;offset&nbsp;in&nbsp;the&nbsp;index&nbsp;file&nbsp;of&nbsp;first&nbsp;record&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;on&nbsp;the&nbsp;hash&nbsp;chain&nbsp;(can&nbsp;be&nbsp;0)&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;offset&nbsp;=&nbsp;_db_readptr(db,&nbsp;db-&gt;ptroff);&nbsp;&nbsp;<BR>&nbsp;while&nbsp;(offset&nbsp;!=&nbsp;0)&nbsp;{&nbsp;&nbsp;<BR>&nbsp;&nbsp;nextoffset&nbsp;=&nbsp;_db_readidx(db,&nbsp;offset);&nbsp;&nbsp;<BR>&nbsp;&nbsp;if&nbsp;(strcmp(db-&gt;idxbuf,&nbsp;key)&nbsp;==&nbsp;0)&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;break;&nbsp;&nbsp;/*&nbsp;found&nbsp;a&nbsp;match&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;&nbsp;db-&gt;ptroff&nbsp;=&nbsp;offset;&nbsp;/*&nbsp;offset&nbsp;of&nbsp;this&nbsp;(unequal)&nbsp;record&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;&nbsp;offset&nbsp;=&nbsp;nextoffset;&nbsp;/*&nbsp;next&nbsp;one&nbsp;to&nbsp;compare&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;}&nbsp;&nbsp;<BR>&nbsp;if&nbsp;(offset&nbsp;==&nbsp;0)&nbsp;&nbsp;<BR>&nbsp;&nbsp;return(-1);&nbsp;&nbsp;/*&nbsp;error,&nbsp;record&nbsp;not&nbsp;found&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;&nbsp;/*&nbsp;We&nbsp;have&nbsp;a&nbsp;match.&nbsp;&nbsp;We're&nbsp;guaranteed&nbsp;that&nbsp;db-&gt;ptroff&nbsp;contains&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;the&nbsp;offset&nbsp;of&nbsp;the&nbsp;chain&nbsp;ptr&nbsp;that&nbsp;points&nbsp;to&nbsp;this&nbsp;matching&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;index&nbsp;record.&nbsp;&nbsp;_db_dodelete()&nbsp;uses&nbsp;this&nbsp;fact.&nbsp;&nbsp;(The&nbsp;chain&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ptr&nbsp;that&nbsp;points&nbsp;to&nbsp;this&nbsp;matching&nbsp;record&nbsp;could&nbsp;be&nbsp;in&nbsp;an&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;index&nbsp;record&nbsp;or&nbsp;in&nbsp;the&nbsp;hash&nbsp;table.)&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;return(0);&nbsp;&nbsp;<BR>}&nbsp;&nbsp;<BR>程序16.8&nbsp;_db_find函数&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;_db_find的最后一个参数指明我们需要加什么样的锁,0表示读锁,1表示写锁&nbsp;&nbsp;<BR>。我们知道,db_fetch需要加读锁,而db_delete和db_store需要加写锁。_db_fi&nbsp;&nbsp;<BR>nd在获得需要的锁之前将等待。&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;_db_find中的while循环遍历Hash链中的索引记录,并比较主键。函数_db_re&nbsp;&nbsp;<BR>adidx用于读取每条索引记录。&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;请注意阅读_db_find中的最后一条注释。当沿着Hash链进行遍历时,必须始终&nbsp;&nbsp;<BR>跟踪索引前一条索引记录,其中有一个指针指向当前记录。这一点在我们删除一条&nbsp;&nbsp;<BR>记录时是很有用的,因为我们必须修改当前索引记录的前一条记录的链指针。&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;让我们先来看看_db_find调用的一些比较简单的函数。_db_hash(程序16.9)&nbsp;&nbsp;<BR>根据给定的主键计算Hash值。它将主键中的每一个ASCII字符乘以这个字符在字符&nbsp;&nbsp;<BR>串中以1开始的索引号,将这些结果加起来,除以Hash表的大小,将余数作为这个&nbsp;&nbsp;<BR>主键的Hash值。&nbsp;&nbsp;<BR>#include&nbsp;&quot;db.h&quot;&nbsp;&nbsp;<BR>/*&nbsp;Calculate&nbsp;the&nbsp;hash&nbsp;value&nbsp;for&nbsp;a&nbsp;key.&nbsp;*/&nbsp;&nbsp;<BR>hash_t&nbsp;&nbsp;<BR>_db_hash(DB&nbsp;*db,&nbsp;const&nbsp;char&nbsp;*key)&nbsp;&nbsp;<BR>{&nbsp;&nbsp;<BR>&nbsp;hash_t&nbsp;&nbsp;hval;&nbsp;&nbsp;<BR>&nbsp;const&nbsp;char&nbsp;*ptr;&nbsp;&nbsp;<BR>&nbsp;char&nbsp;&nbsp;c;&nbsp;&nbsp;<BR>&nbsp;int&nbsp;&nbsp;&nbsp;i;&nbsp;&nbsp;<BR>&nbsp;hval&nbsp;=&nbsp;0;&nbsp;&nbsp;<BR>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -