home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************************/
- /* */
- /* */
- /* db_ran.c (c) 1987 Ken Harris */
- /* */
- /* */
- /****************************************************************************/
- /* */
- /* This software is made available on an AS-IS basis. Unrestricted */
- /* use is granted provided that the copywrite notice remains intack. */
- /* The author makes no warranties expressed or implied. */
- /* */
- /****************************************************************************/
-
- #include <stdio.h>
- #ifdef MSC
- #include <fcntl.h>
- #include <sys\types.h>
- #include <sys\stat.h>
- #endif
- #include "db.h"
-
- /*
- * db_add_ran - Add a record to a random file
- */
-
- void db_add_ran(ds, user_data)
- DATA_SET ds;
- char *user_data;
- {
- FILE_HDR fh;
- RANDOM_HDR rhdr, thdr;
- RANDOM_REC rrec;
- BUFFER buf, tmp;
- short hval;
- char *rbuf;
-
- db_error = 0;
-
- fh = (FILE_HDR) ds->ds_fhdr->buf_data;
- buf = ds->ds_buf;
- tmp = ds->ds_tmp;
- rhdr = (RANDOM_HDR) buf->buf_data;
- thdr = (RANDOM_HDR) tmp->buf_data;
-
- hval = db_hash_ran(ds, user_data);
-
- db_get_blk(ds, (long) hval, buf);
- if (db_error) return;
-
- if (rhdr->ran_stat != DB_INUSE)
- { db_error = DB_INVALID_RANDOM;
- return;
- }
-
- if (db_search_blk_ran(ds, user_data, buf))
- { db_error = DB_DUP_NOT_ALLOWED;
- return;
- }
-
- while (rhdr->ran_next)
- { db_get_blk(ds, (long) rhdr->ran_next, buf);
- if (db_error) return;
-
- if (db_search_blk_ran(ds, user_data, buf))
- { db_error = DB_DUP_NOT_ALLOWED;
- return;
- }
- }
-
- tmp->buf_cur_blk = 0;
- if (rhdr->ran_rec_cnt >= fh->fh_recs_per_blk)
- { buf = ds->ds_tmp;
- tmp = ds->ds_buf;
- ds->ds_buf = buf;
- ds->ds_tmp = tmp;
- rhdr = (RANDOM_HDR) buf->buf_data;
- thdr = (RANDOM_HDR) tmp->buf_data;
-
- db_get_next_avail(ds, buf);
- if (db_error) return;
-
- rhdr->ran_next = 0;
- thdr->ran_next = buf->buf_cur_blk;
-
- }
-
- rbuf = buf->buf_data + sizeof(struct db_random_hdr)
- + rhdr->ran_rec_cnt * fh->fh_rec_size;
- rrec = (RANDOM_REC) rbuf;
-
- if (rrec->ran_stat != DB_FREE)
- { db_error = DB_INVALID_FREE;
- return;
- }
- memcpy(rbuf+fh->fh_ctl_size, user_data, fh->fh_data_size);
- rrec->ran_stat = DB_INUSE;
-
- rhdr->ran_rec_cnt += 1;
- db_add_blk = buf->buf_cur_blk;
- db_add_rec = rhdr->ran_rec_cnt;
-
- fh->fh_rec_cnt += 1;
-
- db_put_blk(ds, buf);
- if (db_error) return;
-
- if (tmp->buf_cur_blk)
- { db_put_blk(ds, tmp);
- if (db_error) return;
- }
-
- db_put_blk(ds, ds->ds_fhdr);
- }
-
- /*
- * db_find_ran - Find a Random record
- */
-
- void db_find_ran(ds, user_data, key)
- DATA_SET ds;
- char *user_data, *key;
- {
- RANDOM_HDR rhdr;
- RANDOM_REC rrec;
- FILE_HDR fh;
- BUFFER buf;
- short hval, rec;
- char *rbuf;
-
- db_error = 0;
-
- fh = (FILE_HDR) ds->ds_fhdr->buf_data;
- buf = ds->ds_buf;
- rhdr = (RANDOM_HDR) buf->buf_data;
-
- hval = db_hash_ran(ds, key);
-
- while (hval)
- { db_get_blk(ds, (long)hval, buf);
- if (db_error) return;
-
- if (rec = db_search_blk_ran(ds, key, buf))
- { buf->buf_rec_inx = rec;
- rbuf = buf->buf_data + sizeof(struct db_random_hdr)
- + (rec - 1) * fh->fh_rec_size;
-
- rrec = (RANDOM_REC) rbuf;
- if (rrec->ran_stat != DB_INUSE)
- { db_error = DB_INVALID_RANDOM;
- return;
- }
- memcpy(user_data, rbuf+fh->fh_ctl_size, fh->fh_data_size);
- return;
- }
- hval = rhdr->ran_next;
- }
- db_error = DB_REC_NOT_FOUND;
- return;
- }
-
- /*
- * db_read_first_ran - Read first record from a random file
- */
-
- void db_read_first_ran(ds, user_data)
- DATA_SET ds;
- char *user_data;
- {
- RANDOM_HDR rhdr;
- RANDOM_REC rrec;
- FILE_HDR fh;
- BUFFER buf;
- ulong blk;
- char *rbuf;
-
- db_error = 0;
-
- fh = (FILE_HDR) ds->ds_fhdr->buf_data;
- buf = ds->ds_buf;
- rhdr = (RANDOM_HDR) buf->buf_data;
-
- for (blk=1; blk <= fh->fh_last_block; blk++)
- { db_get_blk(ds, blk, buf);
- if (db_error) return;
-
- if (rhdr->ran_stat == DB_INUSE && rhdr->ran_rec_cnt > 0)
- { buf->buf_rec_inx = 1;
- rbuf = buf->buf_data + sizeof(struct db_random_hdr);
-
- rrec = (RANDOM_REC) rbuf;
- if (rrec->ran_stat != DB_INUSE)
- { db_error = DB_INVALID_RANDOM;
- return;
- }
- memcpy(user_data, rbuf+fh->fh_ctl_size, fh->fh_data_size);
- return;
- }
- }
- db_error = DB_END_OF_FILE;
- return;
- }
-
- /*
- * db_read_next_ran - Read next record from a random file
- */
-
- void db_read_next_ran(ds, user_data)
- DATA_SET ds;
- char *user_data;
- {
- RANDOM_HDR rhdr;
- RANDOM_REC rrec;
- FILE_HDR fh;
- BUFFER buf;
- ulong blk;
- ushort rec;
- char *rbuf;
-
- db_error = 0;
-
- fh = (FILE_HDR) ds->ds_fhdr->buf_data;
- buf = ds->ds_buf;
- rhdr = (RANDOM_HDR) buf->buf_data;
-
- if (ds->ds_prev_rec < fh->fh_recs_per_blk)
- { blk = ds->ds_prev_blk;
- rec = ds->ds_prev_rec;
- }
- else
- { blk = ds->ds_prev_blk + 1;
- rec = 0;
- }
-
- for (; blk <= fh->fh_last_block; blk++, rec=0)
- { db_get_blk(ds, blk, buf);
- if (db_error) return;
-
- if (rhdr->ran_stat != DB_INUSE) continue;
- if (rhdr->ran_rec_cnt <= rec) continue;
-
-
- buf->buf_rec_inx = rec + 1;
- rbuf = buf->buf_data + sizeof(struct db_random_hdr)
- + (buf->buf_rec_inx - 1) * fh->fh_rec_size;
-
- rrec = (RANDOM_REC) rbuf;
- if (rrec->ran_stat != DB_INUSE)
- { db_error = DB_INVALID_RANDOM;
- return;
- }
- memcpy(user_data, rbuf+fh->fh_ctl_size, fh->fh_data_size);
- return;
- }
- db_error = DB_END_OF_FILE;
- return;
- }
-
- /*
- * db_read_last_ran - Read last record from a random file
- */
-
- void db_read_last_ran(ds, user_data)
- DATA_SET ds;
- char *user_data;
- {
- RANDOM_HDR rhdr;
- RANDOM_REC rrec;
- FILE_HDR fh;
- BUFFER buf;
- ulong blk;
- char *rbuf;
-
- db_error = 0;
-
- fh = (FILE_HDR) ds->ds_fhdr->buf_data;
- buf = ds->ds_buf;
- rhdr = (RANDOM_HDR) buf->buf_data;
-
- for (blk=fh->fh_last_block; blk >= 1; blk--)
- { db_get_blk(ds, blk, buf);
- if (db_error) return;
-
- if (rhdr->ran_stat == DB_INUSE && rhdr->ran_rec_cnt > 0)
- { buf->buf_rec_inx = rhdr->ran_rec_cnt;
- rbuf = buf->buf_data + sizeof(struct db_random_hdr)
- + (rhdr->ran_rec_cnt - 1) * fh->fh_rec_size;
-
- rrec = (RANDOM_REC) rbuf;
- if (rrec->ran_stat != DB_INUSE)
- { db_error = DB_INVALID_RANDOM;
- return;
- }
- memcpy(user_data, rbuf+fh->fh_ctl_size, fh->fh_data_size);
- return;
- }
- }
- db_error = DB_END_OF_FILE;
- return;
- }
-
- /*
- * db_read_prev_ran - Read next record from a random file
- */
-
- void db_read_prev_ran(ds, user_data)
- DATA_SET ds;
- char *user_data;
- {
- RANDOM_HDR rhdr;
- RANDOM_REC rrec;
- FILE_HDR fh;
- BUFFER buf;
- ulong blk;
- ushort rec;
- char *rbuf;
-
- db_error = 0;
-
- fh = (FILE_HDR) ds->ds_fhdr->buf_data;
- buf = ds->ds_buf;
- rhdr = (RANDOM_HDR) buf->buf_data;
-
- if (ds->ds_prev_rec > 1)
- { blk = ds->ds_prev_blk;
- rec = ds->ds_prev_rec - 1;
- }
- else
- { blk = ds->ds_prev_blk - 1;
- rec = 0;
- }
-
- for (; blk >= 1; blk--, rec=0)
- { db_get_blk(ds, blk, buf);
- if (db_error) return;
-
- if (rhdr->ran_stat != DB_INUSE) continue;
- if (!rhdr->ran_rec_cnt) continue;
-
- if (rec)
- buf->buf_rec_inx = rec;
- else
- buf->buf_rec_inx = rhdr->ran_rec_cnt;
-
- rbuf = buf->buf_data + sizeof(struct db_random_hdr)
- + (buf->buf_rec_inx - 1) * fh->fh_rec_size;
-
- rrec = (RANDOM_REC) rbuf;
- if (rrec->ran_stat != DB_INUSE)
- { db_error = DB_INVALID_RANDOM;
- return;
- }
- memcpy(user_data, rbuf+fh->fh_ctl_size, fh->fh_data_size);
- return;
- }
- db_error = DB_END_OF_FILE;
- return;
- }
-
-
- /*
- * db_update_ran - Update a random record
- */
-
- void db_update_ran(ds, user_data)
- DATA_SET ds;
- char *user_data;
- {
- RANDOM_HDR rhdr;
- RANDOM_REC rrec;
- FILE_HDR fh;
- BUFFER buf;
- char *rbuf;
-
- db_error = 0;
-
- fh = (FILE_HDR) ds->ds_fhdr->buf_data;
- buf = ds->ds_buf;
- rhdr = (RANDOM_HDR) buf->buf_data;
-
- if (rhdr->ran_rec_cnt < buf->buf_rec_inx)
- { db_error = DB_DELETED_REC;
- return;
- }
-
- rbuf = buf->buf_data + sizeof(struct db_random_hdr)
- + (buf->buf_rec_inx - 1) * fh->fh_rec_size;
-
- rrec = (RANDOM_REC) rbuf;
- if (rrec->ran_stat != DB_INUSE)
- { db_error = DB_INVALID_RANDOM;
- return;
- }
- memcpy(rbuf+fh->fh_ctl_size, user_data, fh->fh_data_size);
- db_put_blk(ds, buf);
- return;
- }
-
- /*
- * db_delete_ran - Delete a random record
- */
-
- void db_delete_ran(ds)
- DATA_SET ds;
- {
- FILE_HDR fh;
- RANDOM_HDR rhdr, thdr;
- RANDOM_REC rrec, trec;
- BUFFER buf, tmp;
- char *rbuf, *tbuf;
- ulong hval, next;
-
- db_error = 0;
-
- fh = (FILE_HDR) ds->ds_fhdr->buf_data;
- buf = ds->ds_buf;
- tmp = ds->ds_tmp;
- rhdr = (RANDOM_HDR) buf->buf_data;
- thdr = (RANDOM_HDR) tmp->buf_data;
-
- if (buf->buf_rec_inx > rhdr->ran_rec_cnt)
- { db_error = DB_DELETED_REC;
- return;
- }
-
- rbuf = buf->buf_data + sizeof(struct db_random_hdr) + fh->fh_ctl_size;
- hval = db_hash_ran(ds, rbuf);
-
- ds->ds_prev_blk = buf->buf_cur_blk;
- ds->ds_prev_rec = buf->buf_rec_inx - 1;
-
- if (!rhdr->ran_next)
- { if (buf->buf_rec_inx < rhdr->ran_rec_cnt)
- { rbuf = buf->buf_data + sizeof(struct db_random_hdr)
- + (buf->buf_rec_inx - 1) * fh->fh_rec_size;
-
- tbuf = buf->buf_data + sizeof(struct db_random_hdr)
- + (rhdr->ran_rec_cnt - 1) * fh->fh_rec_size;
-
- rrec = (RANDOM_REC) rbuf;
- if (rrec->ran_stat != DB_INUSE)
- { db_error = DB_INVALID_RANDOM;
- return;
- }
- memcpy(rbuf, tbuf, fh->fh_rec_size);
- memset(tbuf, 0, fh->fh_rec_size);
-
- trec = (RANDOM_REC) tbuf;
- trec->ran_stat = DB_FREE;
- }
- else
- if (buf->buf_rec_inx == rhdr->ran_rec_cnt)
- { rbuf = buf->buf_data + sizeof(struct db_random_hdr)
- + (buf->buf_rec_inx - 1) * fh->fh_rec_size;
-
- rrec = (RANDOM_REC) rbuf;
- if (rrec->ran_stat != DB_INUSE)
- { db_error = DB_INVALID_RANDOM;
- return;
- }
-
- memset(rbuf, 0, fh->fh_rec_size);
-
- rrec = (RANDOM_REC) rbuf;
- rrec->ran_stat = DB_FREE;
- }
-
- rhdr->ran_rec_cnt--;
- db_put_blk(ds, buf);
- if (db_error) return;
-
- if (!rhdr->ran_rec_cnt)
- { db_delete_blk_ran(ds, hval);
- return;
- }
- return;
- }
-
- if (rhdr->ran_next)
- { next = rhdr->ran_next;
- while (next)
- { db_get_blk(ds, next, tmp);
- if (db_error) return;
-
- next = thdr->ran_next;
- }
-
- if (!thdr->ran_rec_cnt)
- { db_error = DB_INVALID_RANDOM;
- return;
- }
-
- rbuf = buf->buf_data + sizeof(struct db_random_hdr)
- + (buf->buf_rec_inx - 1) * fh->fh_rec_size;
-
- tbuf = tmp->buf_data + sizeof(struct db_random_hdr)
- + (thdr->ran_rec_cnt - 1) * fh->fh_rec_size;
-
- rrec = (RANDOM_REC) rbuf;
- if (rrec->ran_stat != DB_INUSE)
- { db_error = DB_INVALID_RANDOM;
- return;
- }
- memcpy(rbuf, tbuf, fh->fh_rec_size);
- memset(tbuf, 0, fh->fh_rec_size);
-
- trec = (RANDOM_REC) tbuf;
- trec->ran_stat = DB_FREE;
-
- thdr->ran_rec_cnt--;
- db_put_blk(ds, buf);
- if (db_error) return;
-
- db_put_blk(ds, tmp);
- if (db_error) return;
-
- if (!thdr->ran_rec_cnt)
- { db_delete_blk_ran(ds, hval);
- return;
- }
- return;
- }
- }
-
- /*
- * db_delete_blk_ran - Delete empty overflow buckets
- * There should be at most one at the end of the chain.
- */
-
- void db_delete_blk_ran(ds, base_blk)
- DATA_SET ds;
- ulong base_blk;
- {
- FILE_HDR fh;
- RANDOM_HDR rhdr, thdr;
- BUFFER buf, tmp;
- ulong next;
-
- db_error = 0;
-
- fh = (FILE_HDR) ds->ds_fhdr->buf_data;
- buf = ds->ds_buf;
- tmp = ds->ds_tmp;
- rhdr = (RANDOM_HDR) buf->buf_data;
- thdr = (RANDOM_HDR) tmp->buf_data;
-
- buf->buf_cur_blk = 0;
- tmp->buf_cur_blk = 0;
-
- next = base_blk;
- while (next)
- { db_get_blk(ds, next, tmp);
- if (db_error) return;
-
- next = thdr->ran_next;
-
- if (!thdr->ran_rec_cnt)
- { if (buf->buf_cur_blk)
- { rhdr->ran_next = next;
- db_put_blk(ds, buf);
- if (db_error) return;
- }
- if (tmp->buf_cur_blk > fh->fh_base_size)
- { db_free_rec(ds, tmp);
- continue;
- }
- }
-
- buf = ds->ds_tmp;
- tmp = ds->ds_buf;
- ds->ds_buf = buf;
- ds->ds_tmp = tmp;
- rhdr = (RANDOM_HDR) buf->buf_data;
- thdr = (RANDOM_HDR) tmp->buf_data;
- }
- }
-
- /*
- * db_hash_ran - Hash a random key
- */
-
- short db_hash_ran(ds, key)
- DATA_SET ds;
- char *key;
- {
- FILE_HDR fh;
- ulong hval = 0l;
- short i;
-
- fh = (FILE_HDR) ds->ds_fhdr->buf_data;
-
- for (i=0; i < fh->fh_key_size; i++) hval += key[i];
-
- hval = (hval % fh->fh_base_size) + 1;
-
- return((short) hval);
- }
-
- /*
- * db_search_blk_ran - Search a random block for matching record
- */
-
- short db_search_blk_ran(ds, key, buf)
- DATA_SET ds;
- char *key;
- BUFFER buf;
- {
- RANDOM_HDR rhdr;
- RANDOM_REC rrec;
- FILE_HDR fh;
- char *rec;
- short r_cnt;
-
- fh = (FILE_HDR) ds->ds_fhdr->buf_data;
- rhdr = (RANDOM_HDR) buf->buf_data;
- rec = buf->buf_data + sizeof(struct db_random_hdr);
-
- for (r_cnt = 1; r_cnt <= rhdr->ran_rec_cnt; r_cnt++)
- { rrec = (RANDOM_REC) rec;
- if (rrec->ran_stat != DB_INUSE)
- { db_error = DB_INVALID_RANDOM;
- return(0);
- }
-
- if (memcmp(key, rec+fh->fh_ctl_size, fh->fh_key_size)==0)
- return(r_cnt);
-
- rec += fh->fh_rec_size;
- }
-
- return(0);
- }