bpp_tree.h File Reference
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <stdint.h>
#include "../../key_value/kv_system.h"
#include "./../dictionary.h"
#include "./../../file/ion_file.h"

Description

Author
public domain code
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1.Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2.Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3.Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Definition in file bpp_tree.h.

Include dependency graph for bpp_tree.h:
This graph shows which files directly or indirectly include this file:

Classes

struct  ion_bpp_open_t
 

Macros

#define ION_CC_EQ   0
 
#define ION_CC_GT   1
 
#define ION_CC_LT   -1
 

Typedefs

typedef long ion_bpp_external_address_t
 
typedef long ion_bpp_address_t
 
typedef char(* ion_bpp_comparison_t) (ion_key_t key1, ion_key_t key2, ion_key_size_t size)
 
typedef ion_boolean_e ion_bpp_bool_t
 
typedef enum ION_BPP_ERR ion_bpp_err_t
 
typedef void * ion_bpp_handle_t
 

Enumerations

enum  ION_BPP_ERR {
  bErrOk, bErrKeyNotFound, bErrDupKeys, bErrSectorSize,
  bErrFileNotOpen, bErrFileExists, bErrIO, bErrMemory
}
 

Functions

ion_bpp_err_t b_open (ion_bpp_open_t info, ion_bpp_handle_t *handle)
 
ion_bpp_err_t b_close (ion_bpp_handle_t handle)
 
ion_bpp_err_t b_insert (ion_bpp_handle_t handle, void *key, ion_bpp_external_address_t rec)
 
ion_bpp_err_t b_update (ion_bpp_handle_t handle, void *key, ion_bpp_external_address_t rec)
 
ion_bpp_err_t b_delete (ion_bpp_handle_t handle, void *key, ion_bpp_external_address_t *rec)
 
ion_bpp_err_t b_get (ion_bpp_handle_t handle, void *key, ion_bpp_external_address_t *rec)
 
ion_bpp_err_t b_find_first_greater_or_equal (ion_bpp_handle_t handle, void *key, void *mkey, ion_bpp_external_address_t *rec)
 
ion_bpp_err_t b_find_first_key (ion_bpp_handle_t handle, void *key, ion_bpp_external_address_t *rec)
 
ion_bpp_err_t b_find_last_key (ion_bpp_handle_t handle, void *key, ion_bpp_external_address_t *rec)
 
ion_bpp_err_t b_find_next_key (ion_bpp_handle_t handle, void *key, ion_bpp_external_address_t *rec)
 

Macro Definition Documentation

#define ION_CC_EQ   0

Definition at line 58 of file bpp_tree.h.

#define ION_CC_GT   1

Definition at line 59 of file bpp_tree.h.

#define ION_CC_LT   -1

Definition at line 60 of file bpp_tree.h.

Typedef Documentation

typedef long ion_bpp_address_t

Definition at line 56 of file bpp_tree.h.

Definition at line 79 of file bpp_tree.h.

typedef char(* ion_bpp_comparison_t) (ion_key_t key1, ion_key_t key2, ion_key_size_t size)

Definition at line 67 of file bpp_tree.h.

typedef enum ION_BPP_ERR ion_bpp_err_t

Definition at line 55 of file bpp_tree.h.

typedef void* ion_bpp_handle_t

Definition at line 86 of file bpp_tree.h.

Enumeration Type Documentation

Enumerator
bErrOk 
bErrKeyNotFound 
bErrDupKeys 
bErrSectorSize 
bErrFileNotOpen 
bErrFileExists 
bErrIO 
bErrMemory 

Definition at line 82 of file bpp_tree.h.

Function Documentation

ion_bpp_err_t b_close ( ion_bpp_handle_t  handle)

Definition at line 1040 of file bpp_tree.c.

1042  {
1043  ion_bpp_h_node_t *h = handle;
1044 
1045  if (h == NULL) {
1046  return bErrOk;
1047  }
1048 
1049  /* flush idx */
1050 #if defined(ARDUINO)
1051 
1052  if (h->fp.file) {
1053 #else
1054 
1055  if (h->fp) {
1056 #endif
1057  flushAll(handle);
1058  ion_fclose(h->fp);
1059  }
1060 
1061  if (h->malloc2) {
1062  free(h->malloc2);
1063  }
1064 
1065  if (h->malloc1) {
1066  free(h->malloc1);
1067  }
1068 
1069  free(h);
1070  return bErrOk;
1071 }
ion_file_handle_t fp
Definition: bpp_tree.c:134
ion_err_t ion_fclose(ion_file_handle_t file)
Definition: ion_file.c:80
static ion_bpp_err_t flushAll(ion_bpp_handle_t handle)
Definition: bpp_tree.c:247

Here is the call graph for this function:

Here is the caller graph for this function:

ion_bpp_err_t b_delete ( ion_bpp_handle_t  handle,
void *  key,
ion_bpp_external_address_t rec 
)

Definition at line 1453 of file bpp_tree.c.

1457  {
1458  int rc; /* return code */
1459  ion_bpp_key_t *mkey; /* match key */
1460  int len; /* length to shift */
1461  int cc; /* condition code */
1462  ion_bpp_buffer_t *buf; /* buffer */
1463  ion_bpp_buffer_t *tmp[4];
1464  unsigned int keyOff;
1465  ion_bpp_bool_t lastGEvalid; /* true if GE branch taken */
1466  ion_bpp_bool_t lastLTvalid; /* true if LT branch taken after GE branch */
1467  ion_bpp_address_t lastGE; /* last childGE traversed */
1468  unsigned int lastGEkey; /* last childGE key traversed */
1469  ion_bpp_buffer_t *root;
1470  ion_bpp_buffer_t *gbuf;
1471 
1472  ion_bpp_h_node_t *h = handle;
1473 
1474  root = &h->root;
1475  gbuf = &h->gbuf;
1476  lastGEvalid = boolean_false;
1477  lastLTvalid = boolean_false;
1478 
1479  buf = root;
1480 
1481  while (1) {
1482  if (leaf(buf)) {
1483  /* set mkey to point to deletion point */
1484  if (search(handle, buf, key, *rec, &mkey, MODE_MATCH) == 0) {
1485  *rec = rec(mkey);
1486  }
1487  else {
1488  return bErrKeyNotFound;
1489  }
1490 
1491  /* shift items GT key to left */
1492  keyOff = mkey - fkey(buf);
1493  len = ks(ct(buf) - 1) - keyOff;
1494 
1495  if (len) {
1496  memmove(mkey, mkey + ks(1), len);
1497  }
1498 
1499  ct(buf)--;
1500 
1501  if ((rc = writeDisk(buf)) != 0) {
1502  return rc;
1503  }
1504 
1505  /* if deleted key is first key, then fixup lastGE key */
1506  if (!keyOff && lastLTvalid) {
1507  ion_bpp_buffer_t *tbuf;
1508  ion_bpp_key_t *tkey;
1509 
1510  if ((rc = readDisk(handle, lastGE, &tbuf)) != 0) {
1511  return rc;
1512  }
1513 
1514  tkey = fkey(tbuf) + lastGEkey;
1515  memcpy(key(tkey), mkey, h->keySize);
1516  rec(tkey) = rec(mkey);
1517 
1518  if ((rc = writeDisk(tbuf)) != 0) {
1519  return rc;
1520  }
1521  }
1522 
1523  nKeysDel++;
1524  break;
1525  }
1526  else {
1527  /* internal node, descend to child */
1528  ion_bpp_buffer_t *cbuf; /* child buf */
1529 
1530  /* read child */
1531  if ((cc = search(handle, buf, key, *rec, &mkey, MODE_MATCH)) < 0) {
1532  if ((rc = readDisk(handle, childLT(mkey), &cbuf)) != 0) {
1533  return rc;
1534  }
1535  }
1536  else {
1537  if ((rc = readDisk(handle, childGE(mkey), &cbuf)) != 0) {
1538  return rc;
1539  }
1540  }
1541 
1542  /* check for room to delete */
1543  if (ct(cbuf) == h->maxCt / 2) {
1544  /* gather 3 bufs and scatter */
1545  if ((rc = gather(handle, buf, &mkey, tmp)) != 0) {
1546  return rc;
1547  }
1548 
1549  /* if last 3 bufs in root, and count is low enough... */
1550  if ((buf == root) && (ct(root) == 2) && (ct(gbuf) < (3 * (3 * h->maxCt)) / 4)) {
1551  /* collapse tree by one level */
1552  scatterRoot(handle);
1553  nNodesDel += 3;
1554  continue;
1555  }
1556 
1557  if ((rc = scatter(handle, buf, mkey, 3, tmp)) != 0) {
1558  return rc;
1559  }
1560 
1561  /* read child */
1562  if ((cc = search(handle, buf, key, *rec, &mkey, MODE_MATCH)) < 0) {
1563  if ((rc = readDisk(handle, childLT(mkey), &cbuf)) != 0) {
1564  return rc;
1565  }
1566  }
1567  else {
1568  if ((rc = readDisk(handle, childGE(mkey), &cbuf)) != 0) {
1569  return rc;
1570  }
1571  }
1572  }
1573 
1574  if ((cc >= 0) || (mkey != fkey(buf))) {
1575  lastGEvalid = boolean_true;
1576  lastLTvalid = boolean_false;
1577  lastGE = buf->adr;
1578  lastGEkey = mkey - fkey(buf);
1579 
1580  if (cc < 0) {
1581  lastGEkey -= ks(1);
1582  }
1583  }
1584  else {
1585  if (lastGEvalid) {
1586  lastLTvalid = boolean_true;
1587  }
1588  }
1589 
1590  buf = cbuf;
1591  }
1592  }
1593 
1594  return bErrOk;
1595 }
ion_boolean_e ion_bpp_bool_t
Definition: bpp_tree.h:79
int nNodesDel
Definition: bpp_tree.c:94
static ion_bpp_err_t gather(ion_bpp_handle_t handle, ion_bpp_buffer_t *pbuf, ion_bpp_key_t **pkey, ion_bpp_buffer_t **tmp)
Definition: bpp_tree.c:816
#define childGE(k)
Definition: bpp_tree.c:77
#define ks(ct)
Definition: bpp_tree.c:89
#define key(k)
Definition: bpp_tree.c:75
ion_bpp_buffer_t root
Definition: bpp_tree.c:139
static ion_bpp_err_t writeDisk(ion_bpp_buffer_t *buf)
Definition: bpp_tree.c:331
long ion_bpp_address_t
Definition: bpp_tree.h:56
#define fkey(b)
Definition: bpp_tree.c:84
ion_bpp_address_t adr
Definition: bpp_tree.c:126
ion_bpp_buffer_t gbuf
Definition: bpp_tree.c:143
char ion_bpp_key_t
Definition: bpp_tree.c:103
#define leaf(b)
Definition: bpp_tree.c:80
static int search(ion_bpp_handle_t handle, ion_bpp_buffer_t *buf, void *key, ion_bpp_external_address_t rec, ion_bpp_key_t **mkey, ion_bpp_mode_e mode)
Definition: bpp_tree.c:424
#define ct(b)
Definition: bpp_tree.c:81
unsigned int maxCt
Definition: bpp_tree.c:146
int nKeysDel
Definition: bpp_tree.c:96
static ion_bpp_err_t readDisk(ion_bpp_handle_t handle, ion_bpp_address_t adr, ion_bpp_buffer_t **b)
Definition: bpp_tree.c:341
#define childLT(k)
Definition: bpp_tree.c:74
#define rec(k)
Definition: bpp_tree.c:76
static ion_bpp_err_t scatterRoot(ion_bpp_handle_t handle)
Definition: bpp_tree.c:553
static ion_bpp_err_t scatter(ion_bpp_handle_t handle, ion_bpp_buffer_t *pbuf, ion_bpp_key_t *pkey, int is, ion_bpp_buffer_t **tmp)
Definition: bpp_tree.c:572

Here is the call graph for this function:

Here is the caller graph for this function:

ion_bpp_err_t b_find_first_greater_or_equal ( ion_bpp_handle_t  handle,
void *  key,
void *  mkey,
ion_bpp_external_address_t rec 
)

Definition at line 1116 of file bpp_tree.c.

1121  {
1122  ion_bpp_key_t *lgeqkey; /* matched key */
1123  ion_bpp_buffer_t *buf; /* buffer */
1124  ion_bpp_err_t rc; /* return code */
1125  int cc;
1126 
1127  ion_bpp_h_node_t *h = handle;
1128 
1129  buf = &h->root;
1130 
1131  /* find key, and return address */
1132  while (1) {
1133  if (leaf(buf)) {
1134  if ((cc = search(handle, buf, key, 0, &lgeqkey, MODE_LLEQ)) > 0) {
1135  if ((lgeqkey - fkey(buf)) / (h->ks) == (ct(buf))) {
1136  return bErrKeyNotFound;
1137  }
1138 
1139  lgeqkey += ks(1);
1140  }
1141 
1142  h->curBuf = buf;
1143  h->curKey = lgeqkey;
1144  memcpy(mkey, key(lgeqkey), h->keySize);
1145  *rec = rec(lgeqkey);
1146 
1147  return bErrOk;
1148  }
1149  else {
1150  cc = search(handle, buf, key, 0, &lgeqkey, MODE_LLEQ);
1151 
1152  if (cc < 0) {
1153  if ((rc = readDisk(handle, childLT(lgeqkey), &buf)) != 0) {
1154  return rc;
1155  }
1156  }
1157  else {
1158  if ((rc = readDisk(handle, childGE(lgeqkey), &buf)) != 0) {
1159  return rc;
1160  }
1161  }
1162  }
1163  }
1164 }
enum ION_BPP_ERR ion_bpp_err_t
#define childGE(k)
Definition: bpp_tree.c:77
#define ks(ct)
Definition: bpp_tree.c:89
#define key(k)
Definition: bpp_tree.c:75
ion_bpp_buffer_t root
Definition: bpp_tree.c:139
#define fkey(b)
Definition: bpp_tree.c:84
char ion_bpp_key_t
Definition: bpp_tree.c:103
#define leaf(b)
Definition: bpp_tree.c:80
static int search(ion_bpp_handle_t handle, ion_bpp_buffer_t *buf, void *key, ion_bpp_external_address_t rec, ion_bpp_key_t **mkey, ion_bpp_mode_e mode)
Definition: bpp_tree.c:424
#define ct(b)
Definition: bpp_tree.c:81
static ion_bpp_err_t readDisk(ion_bpp_handle_t handle, ion_bpp_address_t adr, ion_bpp_buffer_t **b)
Definition: bpp_tree.c:341
ion_bpp_buffer_t * curBuf
Definition: bpp_tree.c:144
#define childLT(k)
Definition: bpp_tree.c:74
#define rec(k)
Definition: bpp_tree.c:76
ion_bpp_key_t * curKey
Definition: bpp_tree.c:145

Here is the call graph for this function:

Here is the caller graph for this function:

ion_bpp_err_t b_find_first_key ( ion_bpp_handle_t  handle,
void *  key,
ion_bpp_external_address_t rec 
)

Definition at line 1598 of file bpp_tree.c.

1602  {
1603  ion_bpp_err_t rc; /* return code */
1604  ion_bpp_buffer_t *buf; /* buffer */
1605 
1606  ion_bpp_h_node_t *h = handle;
1607 
1608  buf = &h->root;
1609 
1610  while (!leaf(buf)) {
1611  if ((rc = readDisk(handle, childLT(fkey(buf)), &buf)) != 0) {
1612  return rc;
1613  }
1614  }
1615 
1616  if (ct(buf) == 0) {
1617  return bErrKeyNotFound;
1618  }
1619 
1620  memcpy(key, key(fkey(buf)), h->keySize);
1621  *rec = rec(fkey(buf));
1622  h->curBuf = buf;
1623  h->curKey = fkey(buf);
1624  return bErrOk;
1625 }
enum ION_BPP_ERR ion_bpp_err_t
#define key(k)
Definition: bpp_tree.c:75
ion_bpp_buffer_t root
Definition: bpp_tree.c:139
#define fkey(b)
Definition: bpp_tree.c:84
#define leaf(b)
Definition: bpp_tree.c:80
#define ct(b)
Definition: bpp_tree.c:81
static ion_bpp_err_t readDisk(ion_bpp_handle_t handle, ion_bpp_address_t adr, ion_bpp_buffer_t **b)
Definition: bpp_tree.c:341
ion_bpp_buffer_t * curBuf
Definition: bpp_tree.c:144
#define childLT(k)
Definition: bpp_tree.c:74
#define rec(k)
Definition: bpp_tree.c:76
ion_bpp_key_t * curKey
Definition: bpp_tree.c:145

Here is the call graph for this function:

Here is the caller graph for this function:

ion_bpp_err_t b_find_last_key ( ion_bpp_handle_t  handle,
void *  key,
ion_bpp_external_address_t rec 
)

Definition at line 1639 of file bpp_tree.c.

1643  {
1644  ion_bpp_err_t rc; /* return code */
1645  ion_bpp_buffer_t *buf; /* buffer */
1646 
1647  ion_bpp_h_node_t *h = handle;
1648 
1649  buf = &h->root;
1650 
1651  while (!leaf(buf)) {
1652  if ((rc = readDisk(handle, childGE(lkey(buf)), &buf)) != 0) {
1653  return rc;
1654  }
1655  }
1656 
1657  if (ct(buf) == 0) {
1658  return bErrKeyNotFound;
1659  }
1660 
1661  memcpy(key, key(lkey(buf)), h->keySize);
1662  *rec = rec(lkey(buf));
1663  h->curBuf = buf;
1664  h->curKey = lkey(buf);
1665  return bErrOk;
1666 }
enum ION_BPP_ERR ion_bpp_err_t
#define childGE(k)
Definition: bpp_tree.c:77
#define key(k)
Definition: bpp_tree.c:75
ion_bpp_buffer_t root
Definition: bpp_tree.c:139
#define lkey(b)
Definition: bpp_tree.c:85
#define leaf(b)
Definition: bpp_tree.c:80
#define ct(b)
Definition: bpp_tree.c:81
static ion_bpp_err_t readDisk(ion_bpp_handle_t handle, ion_bpp_address_t adr, ion_bpp_buffer_t **b)
Definition: bpp_tree.c:341
ion_bpp_buffer_t * curBuf
Definition: bpp_tree.c:144
#define rec(k)
Definition: bpp_tree.c:76
ion_bpp_key_t * curKey
Definition: bpp_tree.c:145

Here is the call graph for this function:

ion_bpp_err_t b_find_next_key ( ion_bpp_handle_t  handle,
void *  key,
ion_bpp_external_address_t rec 
)

Definition at line 1669 of file bpp_tree.c.

1673  {
1674  ion_bpp_err_t rc; /* return code */
1675  ion_bpp_key_t *nkey; /* next key */
1676  ion_bpp_buffer_t *buf; /* buffer */
1677 
1678  ion_bpp_h_node_t *h = handle;
1679 
1680  if ((buf = h->curBuf) == NULL) {
1681  return bErrKeyNotFound;
1682  }
1683 
1684  if (h->curKey == lkey(buf)) {
1685  /* current key is last key in leaf node */
1686  if (next(buf)) {
1687  /* fetch next set */
1688  if ((rc = readDisk(handle, next(buf), &buf)) != 0) {
1689  return rc;
1690  }
1691 
1692  nkey = fkey(buf);
1693  }
1694  else {
1695  /* no more sets */
1696  return bErrKeyNotFound;
1697  }
1698  }
1699  else {
1700  /* bump to next key */
1701  nkey = h->curKey + ks(1);
1702  }
1703 
1704  memcpy(key, key(nkey), h->keySize);
1705  *rec = rec(nkey);
1706  h->curBuf = buf;
1707  h->curKey = nkey;
1708  return bErrOk;
1709 }
enum ION_BPP_ERR ion_bpp_err_t
#define next(b)
Definition: bpp_tree.c:82
#define ks(ct)
Definition: bpp_tree.c:89
#define key(k)
Definition: bpp_tree.c:75
#define fkey(b)
Definition: bpp_tree.c:84
#define lkey(b)
Definition: bpp_tree.c:85
char ion_bpp_key_t
Definition: bpp_tree.c:103
static ion_bpp_err_t readDisk(ion_bpp_handle_t handle, ion_bpp_address_t adr, ion_bpp_buffer_t **b)
Definition: bpp_tree.c:341
ion_bpp_buffer_t * curBuf
Definition: bpp_tree.c:144
#define rec(k)
Definition: bpp_tree.c:76
ion_bpp_key_t * curKey
Definition: bpp_tree.c:145

Here is the call graph for this function:

Here is the caller graph for this function:

ion_bpp_err_t b_get ( ion_bpp_handle_t  handle,
void *  key,
ion_bpp_external_address_t rec 
)

Definition at line 1074 of file bpp_tree.c.

1078  {
1079  ion_bpp_key_t *mkey; /* matched key */
1080  ion_bpp_buffer_t *buf; /* buffer */
1081  ion_bpp_err_t rc; /* return code */
1082 
1083  ion_bpp_h_node_t *h = handle;
1084 
1085  buf = &h->root;
1086 
1087  /* find key, and return address */
1088  while (1) {
1089  if (leaf(buf)) {
1090  if (search(handle, buf, key, 0, &mkey, MODE_FIRST) == 0) {
1091  *rec = rec(mkey);
1092  h->curBuf = buf;
1093  h->curKey = mkey;
1094  return bErrOk;
1095  }
1096  else {
1097  return bErrKeyNotFound;
1098  }
1099  }
1100  else {
1101  if (search(handle, buf, key, 0, &mkey, MODE_MATCH) < 0) {
1102  if ((rc = readDisk(handle, childLT(mkey), &buf)) != 0) {
1103  return rc;
1104  }
1105  }
1106  else {
1107  if ((rc = readDisk(handle, childGE(mkey), &buf)) != 0) {
1108  return rc;
1109  }
1110  }
1111  }
1112  }
1113 }
enum ION_BPP_ERR ion_bpp_err_t
#define childGE(k)
Definition: bpp_tree.c:77
#define key(k)
Definition: bpp_tree.c:75
ion_bpp_buffer_t root
Definition: bpp_tree.c:139
char ion_bpp_key_t
Definition: bpp_tree.c:103
#define leaf(b)
Definition: bpp_tree.c:80
static int search(ion_bpp_handle_t handle, ion_bpp_buffer_t *buf, void *key, ion_bpp_external_address_t rec, ion_bpp_key_t **mkey, ion_bpp_mode_e mode)
Definition: bpp_tree.c:424
static ion_bpp_err_t readDisk(ion_bpp_handle_t handle, ion_bpp_address_t adr, ion_bpp_buffer_t **b)
Definition: bpp_tree.c:341
ion_bpp_buffer_t * curBuf
Definition: bpp_tree.c:144
#define childLT(k)
Definition: bpp_tree.c:74
#define rec(k)
Definition: bpp_tree.c:76
ion_bpp_key_t * curKey
Definition: bpp_tree.c:145

Here is the call graph for this function:

Here is the caller graph for this function:

ion_bpp_err_t b_insert ( ion_bpp_handle_t  handle,
void *  key,
ion_bpp_external_address_t  rec 
)

Definition at line 1167 of file bpp_tree.c.

1171  {
1172  int rc; /* return code */
1173  ion_bpp_key_t *mkey; /* match key */
1174  int len; /* length to shift */
1175  int cc; /* condition code */
1176  ion_bpp_buffer_t *buf, *root;
1177  ion_bpp_buffer_t *tmp[4];
1178  unsigned int keyOff;
1179  ion_bpp_bool_t lastGEvalid; /* true if GE branch taken */
1180  ion_bpp_bool_t lastLTvalid; /* true if LT branch taken after GE branch */
1181  ion_bpp_address_t lastGE; /* last childGE traversed */
1182  unsigned int lastGEkey; /* last childGE key traversed */
1183  int height; /* height of tree */
1184 
1185  ion_bpp_h_node_t *h = handle;
1186 
1187  root = &h->root;
1188  lastGEvalid = boolean_false;
1189  lastLTvalid = boolean_false;
1190 
1191  /* check for full root */
1192  if (ct(root) == 3 * h->maxCt) {
1193  /* gather root and scatter to 4 bufs */
1194  /* this increases b-tree height by 1 */
1195  if ((rc = gatherRoot(handle)) != 0) {
1196  return rc;
1197  }
1198 
1199  if ((rc = scatter(handle, root, fkey(root), 0, tmp)) != 0) {
1200  return rc;
1201  }
1202  }
1203 
1204  buf = root;
1205  height = 0;
1206 
1207  while (1) {
1208  if (leaf(buf)) {
1209  /* in leaf, and there' room guaranteed */
1210 
1211  if (height > maxHeight) {
1212  maxHeight = height;
1213  }
1214 
1215  /* set mkey to point to insertion point */
1216  switch (search(handle, buf, key, rec, &mkey, MODE_MATCH)) {
1217  case ION_CC_LT: /* key < mkey */
1218 
1219  if (!h->dupKeys && (0 != ct(buf)) && (h->comp(key, mkey, (ion_key_size_t) (h->keySize)) == ION_CC_EQ)) {
1220  return bErrDupKeys;
1221  }
1222 
1223  break;
1224 
1225  case ION_CC_EQ: /* key = mkey */
1226  return bErrDupKeys;
1227  break;
1228 
1229  case ION_CC_GT: /* key > mkey */
1230 
1231  if (!h->dupKeys && (h->comp(key, mkey, (ion_key_size_t) (h->keySize)) == ION_CC_EQ)) {
1232  return bErrDupKeys;
1233  }
1234 
1235  mkey += ks(1);
1236  break;
1237  }
1238 
1239  /* shift items GE key to right */
1240  keyOff = mkey - fkey(buf);
1241  len = ks(ct(buf)) - keyOff;
1242 
1243  if (len) {
1244  memmove(mkey + ks(1), mkey, len);
1245  }
1246 
1247  /* insert new key */
1248  memcpy(key(mkey), key, h->keySize);
1249  rec(mkey) = rec;
1250  childGE(mkey) = 0;
1251  ct(buf)++;
1252 
1253  if ((rc = writeDisk(buf)) != 0) {
1254  return rc;
1255  }
1256 
1257  /* if new key is first key, then fixup lastGE key */
1258  if (!keyOff && lastLTvalid) {
1259  ion_bpp_buffer_t *tbuf;
1260  ion_bpp_key_t *tkey;
1261 
1262  if ((rc = readDisk(handle, lastGE, &tbuf)) != 0) {
1263  return rc;
1264  }
1265 
1266  /* tkey = fkey(tbuf) + lastGEkey; */
1267  tkey = fkey(tbuf);
1268  memcpy(key(tkey), key, h->keySize);
1269  rec(tkey) = rec;
1270 
1271  if ((rc = writeDisk(tbuf)) != 0) {
1272  return rc;
1273  }
1274  }
1275 
1276  nKeysIns++;
1277  break;
1278  }
1279  else {
1280  /* internal node, descend to child */
1281  ion_bpp_buffer_t *cbuf; /* child buf */
1282 
1283  height++;
1284 
1285  /* read child */
1286  if ((cc = search(handle, buf, key, rec, &mkey, MODE_MATCH)) < 0) {
1287  if ((rc = readDisk(handle, childLT(mkey), &cbuf)) != 0) {
1288  return rc;
1289  }
1290  }
1291  else {
1292  if ((rc = readDisk(handle, childGE(mkey), &cbuf)) != 0) {
1293  return rc;
1294  }
1295  }
1296 
1297  /* check for room in child */
1298  if (ct(cbuf) == h->maxCt) {
1299  /* gather 3 bufs and scatter */
1300  if ((rc = gather(handle, buf, &mkey, tmp)) != 0) {
1301  return rc;
1302  }
1303 
1304  if ((rc = scatter(handle, buf, mkey, 3, tmp)) != 0) {
1305  return rc;
1306  }
1307 
1308  /* read child */
1309  if ((cc = search(handle, buf, key, rec, &mkey, MODE_MATCH)) < 0) {
1310  if ((rc = readDisk(handle, childLT(mkey), &cbuf)) != 0) {
1311  return rc;
1312  }
1313  }
1314  else {
1315  if ((rc = readDisk(handle, childGE(mkey), &cbuf)) != 0) {
1316  return rc;
1317  }
1318  }
1319  }
1320 
1321  if ((cc >= 0) || (mkey != fkey(buf))) {
1322  lastGEvalid = boolean_true;
1323  lastLTvalid = boolean_false;
1324  lastGE = buf->adr;
1325  lastGEkey = mkey - fkey(buf);
1326 
1327  if (cc < 0) {
1328  lastGEkey -= ks(1);
1329  }
1330  }
1331  else {
1332  if (lastGEvalid) {
1333  lastLTvalid = boolean_true;
1334  }
1335  }
1336 
1337  buf = cbuf;
1338  }
1339  }
1340 
1341  return bErrOk;
1342 }
int maxHeight
Definition: bpp_tree.c:92
ion_boolean_e ion_bpp_bool_t
Definition: bpp_tree.h:79
static ion_bpp_err_t gather(ion_bpp_handle_t handle, ion_bpp_buffer_t *pbuf, ion_bpp_key_t **pkey, ion_bpp_buffer_t **tmp)
Definition: bpp_tree.c:816
#define childGE(k)
Definition: bpp_tree.c:77
#define ks(ct)
Definition: bpp_tree.c:89
#define key(k)
Definition: bpp_tree.c:75
ion_bpp_buffer_t root
Definition: bpp_tree.c:139
static ion_bpp_err_t writeDisk(ion_bpp_buffer_t *buf)
Definition: bpp_tree.c:331
long ion_bpp_address_t
Definition: bpp_tree.h:56
#define fkey(b)
Definition: bpp_tree.c:84
ion_bpp_address_t adr
Definition: bpp_tree.c:126
#define ION_CC_LT
Definition: bpp_tree.h:60
char ion_bpp_key_t
Definition: bpp_tree.c:103
#define leaf(b)
Definition: bpp_tree.c:80
static ion_bpp_err_t gatherRoot(ion_bpp_handle_t handle)
Definition: bpp_tree.c:799
static int search(ion_bpp_handle_t handle, ion_bpp_buffer_t *buf, void *key, ion_bpp_external_address_t rec, ion_bpp_key_t **mkey, ion_bpp_mode_e mode)
Definition: bpp_tree.c:424
#define ct(b)
Definition: bpp_tree.c:81
int nKeysIns
Definition: bpp_tree.c:95
ion_bpp_bool_t dupKeys
Definition: bpp_tree.c:136
unsigned int maxCt
Definition: bpp_tree.c:146
#define ION_CC_EQ
Definition: bpp_tree.h:58
static ion_bpp_err_t readDisk(ion_bpp_handle_t handle, ion_bpp_address_t adr, ion_bpp_buffer_t **b)
Definition: bpp_tree.c:341
#define childLT(k)
Definition: bpp_tree.c:74
#define rec(k)
Definition: bpp_tree.c:76
int ion_key_size_t
The size (length) of a dictionary key in bytes.
Definition: kv_system.h:251
#define ION_CC_GT
Definition: bpp_tree.h:59
ion_bpp_comparison_t comp
Definition: bpp_tree.c:138
static ion_bpp_err_t scatter(ion_bpp_handle_t handle, ion_bpp_buffer_t *pbuf, ion_bpp_key_t *pkey, int is, ion_bpp_buffer_t **tmp)
Definition: bpp_tree.c:572

Here is the call graph for this function:

Here is the caller graph for this function:

ion_bpp_err_t b_open ( ion_bpp_open_t  info,
ion_bpp_handle_t handle 
)

Definition at line 899 of file bpp_tree.c.

902  {
903  ion_bpp_h_node_t *h;
904  ion_bpp_err_t rc; /* return code */
905  int bufCt; /* number of tmp buffers */
906  ion_bpp_buffer_t *buf; /* buffer */
907  int maxCt; /* maximum number of keys in a node */
908  ion_bpp_buffer_t *root;
909  int i;
910  ion_bpp_node_t *p;
911 
912  if ((info.sectorSize < sizeof(ion_bpp_h_node_t)) || (0 != info.sectorSize % 4)) {
913  return bErrSectorSize;
914  }
915 
916  /* determine sizes and offsets */
917  /* leaf/n, prev, next, [childLT,key,rec]... childGE */
918  /* ensure that there are at least 3 children/parent for gather/scatter */
919  maxCt = info.sectorSize - (sizeof(ion_bpp_node_t) - sizeof(ion_bpp_key_t));
920  maxCt /= sizeof(ion_bpp_address_t) + info.keySize + sizeof(ion_bpp_external_address_t);
921 
922  if (maxCt < 6) {
923  return bErrSectorSize;
924  }
925 
926  /* copy parms to ion_bpp_h_node_t */
927  if ((h = calloc(1, sizeof(ion_bpp_h_node_t))) == NULL) {
928  return error(bErrMemory);
929  }
930 
931  h->keySize = info.keySize;
932  h->dupKeys = info.dupKeys;
933  h->sectorSize = info.sectorSize;
934  h->comp = info.comp;
935 
936  /* childLT, key, rec */
937  h->ks = sizeof(ion_bpp_address_t) + h->keySize + sizeof(ion_bpp_external_address_t);
938  h->maxCt = maxCt;
939 
940  /* Allocate buflist.
941  * During insert/delete, need simultaneous access to 7 buffers:
942  * - 4 adjacent child bufs
943  * - 1 parent buf
944  * - 1 next sequential link
945  * - 1 lastGE
946  */
947  bufCt = 7;
948 
949  if ((h->malloc1 = calloc(bufCt, sizeof(ion_bpp_buffer_t))) == NULL) {
950  return error(bErrMemory);
951  }
952 
953  buf = h->malloc1;
954 
955  /*
956  * Allocate bufs.
957  * We need space for the following:
958  * - bufCt buffers, of size sectorSize
959  * - 1 buffer for root, of size 3*sectorSize
960  * - 1 buffer for gbuf, size 3*sectorsize + 2 extra keys
961  * to allow for LT pointers in last 2 nodes when gathering 3 full nodes
962  */
963  if ((h->malloc2 = malloc((bufCt + 6) * h->sectorSize + 2 * h->ks)) == NULL) {
964  return error(bErrMemory);
965  }
966 
967  for (i = 0; i < (bufCt + 6) * h->sectorSize + 2 * h->ks; i++) {
968  ((char *) h->malloc2)[i] = 0;
969  }
970 
971  p = h->malloc2;
972 
973  /* initialize buflist */
974  h->bufList.next = buf;
975  h->bufList.prev = buf + (bufCt - 1);
976 
977  for (i = 0; i < bufCt; i++) {
978  buf->next = buf + 1;
979  buf->prev = buf - 1;
980  buf->modified = boolean_false;
981  buf->valid = boolean_false;
982  buf->p = p;
983  p = (ion_bpp_node_t *) ((char *) p + h->sectorSize);
984  buf++;
985  }
986 
987  h->bufList.next->prev = &h->bufList;
988  h->bufList.prev->next = &h->bufList;
989 
990  /* initialize root */
991  root = &h->root;
992  root->p = p;
993  p = (ion_bpp_node_t *) ((char *) p + 3 * h->sectorSize);
994  h->gbuf.p = p;/* done last to include extra 2 keys */
995 
996  h->curBuf = NULL;
997  h->curKey = NULL;
998 
999  /* initialize root */
1000  if (ion_fexists(info.iName)) {
1001  /* open an existing database */
1002  h->fp = ion_fopen(info.iName);
1003 
1004  if ((rc = readDisk(h, 0, &root)) != 0) {
1005  return rc;
1006  }
1007 
1008  if (ion_fseek(h->fp, 0, ION_FILE_END)) {
1009  return error(bErrIO);
1010  }
1011 
1012  if ((h->nextFreeAdr = ion_ftell(h->fp)) == -1) {
1013  return error(bErrIO);
1014  }
1015  }
1016 
1017 #if defined(ARDUINO)
1018  else if (NULL != (h->fp = ion_fopen(info.iName)).file) {
1019 #else
1020  else if (NULL != (h->fp = ion_fopen(info.iName))) {
1021 #endif
1022  /* initialize root */
1023  memset(root->p, 0, 3 * h->sectorSize);
1024  leaf(root) = 1;
1025  h->nextFreeAdr = 3 * h->sectorSize;
1026  root->modified = 1;
1027  flushAll(h);
1028  }
1029  else {
1030  /* something's wrong */
1031  free(h);
1032  return bErrFileNotOpen;
1033  }
1034 
1035  *handle = h;
1036  return bErrOk;
1037 }
ion_bpp_bool_t dupKeys
Definition: bpp_tree.h:92
enum ION_BPP_ERR ion_bpp_err_t
ion_boolean_t ion_fexists(char *name)
Definition: ion_file.c:40
ion_bpp_node_t * p
Definition: bpp_tree.c:127
ion_file_handle_t fp
Definition: bpp_tree.c:134
#define ION_FILE_END
Definition: ion_file.h:50
size_t sectorSize
Definition: bpp_tree.h:93
ion_bpp_buffer_t root
Definition: bpp_tree.c:139
long ion_bpp_address_t
Definition: bpp_tree.h:56
ion_err_t ion_fseek(ion_file_handle_t file, ion_file_offset_t seek_to, int origin)
Definition: ion_file.c:109
ion_bpp_comparison_t comp
Definition: bpp_tree.h:94
ion_file_handle_t ion_fopen(char *name)
Definition: ion_file.c:51
ion_bpp_buffer_t gbuf
Definition: bpp_tree.c:143
char ion_bpp_key_t
Definition: bpp_tree.c:103
ion_bpp_address_t nextFreeAdr
Definition: bpp_tree.c:148
long ion_bpp_external_address_t
Definition: bpp_tree.h:55
#define leaf(b)
Definition: bpp_tree.c:80
ion_bpp_bool_t dupKeys
Definition: bpp_tree.c:136
unsigned int maxCt
Definition: bpp_tree.c:146
ion_bpp_bool_t valid
Definition: bpp_tree.c:128
struct ion_bpp_buffer_tag * next
Definition: bpp_tree.c:124
ion_bpp_buffer_t bufList
Definition: bpp_tree.c:140
static ion_bpp_err_t readDisk(ion_bpp_handle_t handle, ion_bpp_address_t adr, ion_bpp_buffer_t **b)
Definition: bpp_tree.c:341
#define error(rc)
Definition: bpp_tree.c:151
ion_bpp_buffer_t * curBuf
Definition: bpp_tree.c:144
struct ion_bpp_buffer_tag * prev
Definition: bpp_tree.c:125
ion_bpp_bool_t modified
Definition: bpp_tree.c:129
#define p(b)
Definition: bpp_tree.c:86
ion_file_offset_t ion_ftell(ion_file_handle_t file)
Definition: ion_file.c:132
ion_bpp_key_t * curKey
Definition: bpp_tree.c:145
char * iName
Definition: bpp_tree.h:90
static ion_bpp_err_t flushAll(ion_bpp_handle_t handle)
Definition: bpp_tree.c:247
ion_bpp_comparison_t comp
Definition: bpp_tree.c:138

Here is the call graph for this function:

Here is the caller graph for this function:

ion_bpp_err_t b_update ( ion_bpp_handle_t  handle,
void *  key,
ion_bpp_external_address_t  rec 
)

Definition at line 1345 of file bpp_tree.c.

1349  {
1350  int rc; /* return code */
1351  ion_bpp_key_t *mkey; /* match key */
1352  int cc; /* condition code */
1353  ion_bpp_buffer_t *buf, *root;
1354  ion_bpp_buffer_t *tmp[4];
1355  int height; /* height of tree */
1356 
1357  ion_bpp_h_node_t *h = handle;
1358 
1359  root = &h->root;
1360 
1361  /* check for full root */
1362  if (ct(root) == 3 * h->maxCt) {
1363  /* gather root and scatter to 4 bufs */
1364  /* this increases b-tree height by 1 */
1365  if ((rc = gatherRoot(handle)) != 0) {
1366  return rc;
1367  }
1368 
1369  if ((rc = scatter(handle, root, fkey(root), 0, tmp)) != 0) {
1370  return rc;
1371  }
1372  }
1373 
1374  buf = root;
1375  height = 0;
1376 
1377  while (1) {
1378  if (leaf(buf)) {
1379  /* in leaf, and there' room guaranteed */
1380 
1381  if (height > maxHeight) {
1382  maxHeight = height;
1383  }
1384 
1385  /* set mkey to point to update point */
1386  switch (search(handle, buf, key, rec, &mkey, MODE_MATCH)) {
1387  case ION_CC_LT: /* key < mkey */
1388  return bErrKeyNotFound;
1389  break;
1390 
1391  case ION_CC_EQ: /* key = mkey */
1392  break;
1393 
1394  case ION_CC_GT: /* key > mkey */
1395  return bErrKeyNotFound;
1396  break;
1397  }
1398 
1399  /* update key */
1400  rec(mkey) = rec;
1401  break;
1402  }
1403  else {
1404  /* internal node, descend to child */
1405  ion_bpp_buffer_t *cbuf; /* child buf */
1406 
1407  height++;
1408 
1409  /* read child */
1410  if ((cc = search(handle, buf, key, rec, &mkey, MODE_MATCH)) < 0) {
1411  if ((rc = readDisk(handle, childLT(mkey), &cbuf)) != 0) {
1412  return rc;
1413  }
1414  }
1415  else {
1416  if ((rc = readDisk(handle, childGE(mkey), &cbuf)) != 0) {
1417  return rc;
1418  }
1419  }
1420 
1421  /* check for room in child */
1422  if (ct(cbuf) == h->maxCt) {
1423  /* gather 3 bufs and scatter */
1424  if ((rc = gather(handle, buf, &mkey, tmp)) != 0) {
1425  return rc;
1426  }
1427 
1428  if ((rc = scatter(handle, buf, mkey, 3, tmp)) != 0) {
1429  return rc;
1430  }
1431 
1432  /* read child */
1433  if ((cc = search(handle, buf, key, rec, &mkey, MODE_MATCH)) < 0) {
1434  if ((rc = readDisk(handle, childLT(mkey), &cbuf)) != 0) {
1435  return rc;
1436  }
1437  }
1438  else {
1439  if ((rc = readDisk(handle, childGE(mkey), &cbuf)) != 0) {
1440  return rc;
1441  }
1442  }
1443  }
1444 
1445  buf = cbuf;
1446  }
1447  }
1448 
1449  return bErrOk;
1450 }
int maxHeight
Definition: bpp_tree.c:92
static ion_bpp_err_t gather(ion_bpp_handle_t handle, ion_bpp_buffer_t *pbuf, ion_bpp_key_t **pkey, ion_bpp_buffer_t **tmp)
Definition: bpp_tree.c:816
#define childGE(k)
Definition: bpp_tree.c:77
#define key(k)
Definition: bpp_tree.c:75
ion_bpp_buffer_t root
Definition: bpp_tree.c:139
#define fkey(b)
Definition: bpp_tree.c:84
#define ION_CC_LT
Definition: bpp_tree.h:60
char ion_bpp_key_t
Definition: bpp_tree.c:103
#define leaf(b)
Definition: bpp_tree.c:80
static ion_bpp_err_t gatherRoot(ion_bpp_handle_t handle)
Definition: bpp_tree.c:799
static int search(ion_bpp_handle_t handle, ion_bpp_buffer_t *buf, void *key, ion_bpp_external_address_t rec, ion_bpp_key_t **mkey, ion_bpp_mode_e mode)
Definition: bpp_tree.c:424
#define ct(b)
Definition: bpp_tree.c:81
unsigned int maxCt
Definition: bpp_tree.c:146
#define ION_CC_EQ
Definition: bpp_tree.h:58
static ion_bpp_err_t readDisk(ion_bpp_handle_t handle, ion_bpp_address_t adr, ion_bpp_buffer_t **b)
Definition: bpp_tree.c:341
#define childLT(k)
Definition: bpp_tree.c:74
#define rec(k)
Definition: bpp_tree.c:76
#define ION_CC_GT
Definition: bpp_tree.h:59
static ion_bpp_err_t scatter(ion_bpp_handle_t handle, ion_bpp_buffer_t *pbuf, ion_bpp_key_t *pkey, int is, ion_bpp_buffer_t **tmp)
Definition: bpp_tree.c:572

Here is the call graph for this function:

Here is the caller graph for this function: