📄 hashdb_low.c
字号:
if (p_idx == HASH_ROOT_NODE) parent = (h_blk_hdr *) (pbuf + HDB_INFHDR_SZ); else parent = (h_blk_hdr *) pbuf; child = (h_blk_hdr *) newbuf; child->id = dbd->nblk - 1; child->free = dbd->blksz - HDB_BLKHDR_SZ; child->parent = parent->id; child->peer = -1; parent->peer = child->id; } /* end of if */ return (rc);} /* end of h_init_new_blk() *//*******************************************************************************\**** Function: int h_init_new_db()** Desc: Initializes a new database** Accepts: char *name = File name** int blocksize = blocksize of each block** int mxhashidx = Maximum index in the hash table to create** Returns: int; 0 on success, -1 on error**\*******************************************************************************/inth_init_new_db(char *name, int blocksize, int mxhashidx){ char *buf; /* Dynamic buffer */ int db_fd = -1, /* Database file descriptor */ perm, /* Create permissions */ rc; /* Return code */ long pagesz; /* Page size */ hashdb_t hashrec; /* Hash database handle */ /* Make sure the blocksize is page aligned */ pagesz = sysconf(_SC_PAGESIZE); if (pagesz == -1) { /* Blocksize is left alone? */ ; } /* end of if */ else if ((blocksize % pagesz)) { /* Do something to align the block size */ blocksize = ((blocksize + pagesz) / pagesz * pagesz); } /* end of else-if */ /* First, check to make sure that the index record will fit on 1 block!!! */ if ((blocksize - (HDB_INFHDR_SZ + HDB_IDXHDR_SZ + HDB_BLKHDR_SZ)) < (mxhashidx * HDB_IDXHDR_SZ)) { /* Not enough space for the index to fit.... */ errno = E2BIG; return (-1); } /* end of if */ buf = (char *) calloc(blocksize, sizeof(char)); if (!buf) return (-1); perm = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; /* open the file, and return an EEXISTS if already exists */ if ((db_fd = open(name, O_RDWR)) > -1) { /* File already exists....see if it is a database file */ if ((rc = read(db_fd, buf, HDB_INFHDR_SZ)) <= 0) { /* Error reading from file, unlink it, and then create it */ close(db_fd); unlink(name); db_fd = -1; } /* end of if */ else { /* Data was read */ h_info_hdr *inf_hdr = (h_info_hdr *) buf; /* Info header of the file */ if (inf_hdr->magic == HASH_MAGIC) { errno = EEXIST; close(db_fd); free(buf); return (-1); } /* end of if */ close(db_fd); unlink(name); db_fd = -1; } /* end of else */ } /* end of if */ free(buf); if (db_fd == -1 && (db_fd = open(name, O_RDWR | O_CREAT | O_TRUNC, perm)) == -1) { /* Could not create the file */ return (db_fd); } // end of if /* Grow the file to the block size, and initialize the root block */ memset(&hashrec, 0, HDB_DBHND_SZ); hashrec.fd = db_fd; hashrec.blksz = blocksize; hashrec.idxsz = mxhashidx; hashrec.mode = O_RDWR; rc = h_makeroot_blk(&hashrec); close(db_fd); if (rc == -1) unlink(name); return (rc);} /* End of h_init_new_db() *//*******************************************************************************\**** Function: int h_makeroot_blk()** Desc: Makes the root block on the newly created file** Accepts: hashdb_t *dbd = Ptr to the hashed db record** Returns: int; 0 on success, -1 on error (errno is set)**\*******************************************************************************/static inth_makeroot_blk(hashdb_t * dbd){ char *rootbuf; /* Dynamic buffer for the root */ int bufsz, /* Buffer size */ rc; /* Result code */ h_info_hdr *infh; /* Ptr into info header */ h_blk_hdr *blkh; /* Ptr to the blkh header */ h_idx_hdr *idxh; /* Ptr into the index header */ /* Make the block */ if ((rc = h_init_new_blk(dbd, HASH_ROOT_NODE - 1)) == -1) { return (-1); } /* end of if */ /* Allocate the buffer */ bufsz = HDB_INFHDR_SZ + HDB_BLKHDR_SZ + HDB_IDXHDR_SZ + (dbd->idxsz * HDB_IDXREC_SZ); /* Figure out how to write this out (either via map or file io) */ rootbuf = (char *) dbd->blk_ar[rc].addr; infh = (h_info_hdr *) rootbuf; blkh = (h_blk_hdr *) (rootbuf + HDB_INFHDR_SZ); idxh = (h_idx_hdr *) (rootbuf + HDB_INFHDR_SZ + HDB_BLKHDR_SZ); /* Fill in the info header stuff */ infh->magic = HASH_MAGIC; infh->blksz = dbd->blksz; infh->nblk = 0; /* Fill in the block header stuff */ blkh->id = HASH_ROOT_NODE; blkh->free = dbd->blksz - bufsz; blkh->parent = -1; blkh->peer = 0; /* Fill in the index header */ idxh->idx_size = dbd->idxsz * HDB_IDXREC_SZ; idxh->idx_max_val = dbd->idxsz; munmap(dbd->blk_ar[rc].addr, dbd->blksz); return (rc);} /* end of h_makeroot_blk() *//*******************************************************************************\**** Function: int h_map_block()** Desc: Maps the requested block into memory** Accepts: hashdb_t *dbd = Ptr to the database handle record** int blkno = Number of the block to map** Returns: int; -1 on error, or the index into the array of the mapped** block**\*******************************************************************************/inth_map_block(hashdb_t * dbd, int blkno){ int i, /* Loop iterator */ mmode = 0, /* Map mode */ rc; /* Result code */ /* Check the sanity of the block */ if ((blkno * dbd->blksz) >= dbd->fsize) { errno = EINVAL; return (-1); } /* end of if */ /* Check to see if this block is already mapped */ for (i = 0; i < dbd->mapcnt; i++) { if (dbd->blk_ar[i].blkno == blkno) return (i); } /* end of for */ /* Map this */ switch (dbd->mode) { case O_RDONLY: mmode = PROT_READ; break; case O_WRONLY: mmode = PROT_WRITE; break; case O_RDWR: mmode = PROT_READ | PROT_WRITE; break; } /* end of switch */ if ((dbd->mapcnt + 1) >= dbd->mapsz) { if (dbd->mapsz == 0) { if ((dbd->blk_ar = (h_blk_map_t *) calloc(5, HDB_MAPREC_SZ)) == NULL) return (-1); } /* end of if */ else { /* Need to reallocate */ h_blk_map_t *tmp; tmp = (h_blk_map_t *) realloc(dbd->blk_ar, ((dbd->mapsz + 5) * HDB_MAPREC_SZ)); if (!tmp) return (-1); dbd->blk_ar = tmp; } /* end of else */ dbd->mapsz += 5; } /* end of if */ /* Seek to this area? */ // lseek(dbd->fd, blkno * dbd->blksz, SEEK_SET); dbd->blk_ar[dbd->mapcnt].addr = mmap(0, dbd->blksz, mmode, MAP_SHARED, dbd->fd, dbd->blksz * blkno); if (dbd->blk_ar[dbd->mapcnt].addr == MAP_FAILED) { rc = -1; } // end of if else { dbd->blk_ar[dbd->mapcnt].blkno = blkno; rc = dbd->mapcnt++; } // end of else return (rc);} /* end of h_map_block() */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -