📄 kafs.c
字号:
** ----------------------------------------------------------------- */
read_rec(int fn, void *buffer)
{
long hblk; /* Hash Block number */
int brec;
char *kp;
if(read_xrec(fn, buffer)==ERR) return(ERR); /* Get Data First */
hblk = (long)rec / ftbl[fn].kpb; /* get the hash index block no. */
if(read_hblk(ftbl[fn].handle, hblk)==ERR) return(ERR);
brec = rec-(hblk * ftbl[fn].kpb); /* Rec # offset into this block */
kp = hbuf + (brec * ftbl[fn].keysize); /* point to the record */
strcpy(key,kp); /* Copy in the Key */
return(OK);
}
/** -----------------------------------------------------------------
** READ_XREC - Internal Access to Read a key access file by Record Number.
** This function reads only the Data portion of a record.
** ----------------------------------------------------------------- */
read_xrec(int fn, void *buffer)
{
long fpos;
if(ftbl[fn].handle == FCLOSED || fn < 0 || fn >= KEYFILES)
{
kaerror = 4; /* File not open */
return(ERR);
}
if(rec > ftbl[fn].records || rec < 0)
{
kaerror = 13; /* Beyond File Limit */
return(ERR);
}
fpos = ((long)rec * ftbl[fn].recsize) + ftbl[fn].dbeg;
if(lseek(ftbl[fn].handle,fpos,0)==ERR)
{
kaerror = 5; /* Seek Error on Data File */
return(ERR);
}
if(read(ftbl[fn].handle, buffer,(unsigned)ftbl[fn].recsize)==ERR)
{
kaerror = 6; /* Read Error on Data File */
return(ERR);
}
return(OK);
}
/** -----------------------------------------------------------------
** WRITE_KEY - Write a new record to a key access file by key.
** This function hashes the key to find the record.
** ----------------------------------------------------------------- */
write_key(int fn, char *keyarg, void *buffer)
{
long hblk;
long startblock; /* Starting point for search */
int brec; /* Record number in Block */
char *hp;
if(ftbl[fn].handle == FCLOSED || fn < 0 || fn >= KEYFILES)
{
kaerror = 4; /* File not open */
return(ERR);
}
if(strlen(keyarg)>ftbl[fn].keysize-1)
{
kaerror = 11; /* key too big */
return(ERR);
}
hblk = khash(keyarg, ftbl[fn].hblocks); /* Get the Hashed Block */
if(read_hblk(ftbl[fn].handle, hblk)==ERR) return(ERR);
hp = hbuf; /* Point to beginning of Buffer */
rec = hblk * ftbl[fn].kpb; /* Calculate record number */
startblock = hblk; /* Save for wrap-arounds */
brec = 0;
while(1)
{
if(*hp < 02) /* Found an Empty Slot, empty (00) or deleted (01) */
{
if(write_rec(fn, buffer)==ERR) return(ERR); /* Write the Data */
strcpy(hp,keyarg); /* Copy in the Key */
if(write_hblk(ftbl[fn].handle, hblk)==ERR) return(ERR);
else return(OK);
}
rec++; /* Bump the record number */
brec++; /* Bump the block record number */
hp += ftbl[fn].keysize; /* Move the Pointer to the next key */
if(brec>=ftbl[fn].kpb)
{
hblk++;
if(hblk >= ftbl[fn].hblocks) hblk=0; /* Wrap around at EOF */
if(hblk == startblock) return(FILEFULL); /* Oops We wrapped around */
if(read_hblk(ftbl[fn].handle, hblk)==ERR) return(ERR); /* Read Nxt Blk */
hp = hbuf; /* Point to beginning of block */
brec = 0;
rec = hblk * ftbl[fn].kpb; /* Calculate Record # */
}
}
}
/** -----------------------------------------------------------------
** WRITE_REC - Write a record to a key access file by Record #.
** This function only writes the Data Portion of a record
**
** 2.0 Modified to add data beginning offset
**
** ----------------------------------------------------------------- */
write_rec(int fn, void *buffer)
{
int fh;
long fpos;
if(ftbl[fn].handle == FCLOSED || fn < 0 || fn >= KEYFILES)
{
kaerror = 4; /* File not open */
return(ERR);
}
if(rec > ftbl[fn].records || rec < 0)
{
kaerror = 13; /* Beyond File Limit */
return(ERR);
}
fh = ftbl[fn].handle; /* Set file handle */
fpos = ((long)rec * ftbl[fn].recsize) + ftbl[fn].dbeg;
if(lseek(fh,fpos,0)==ERR)
{
kaerror = 5; /* Seek Error */
return(ERR);
}
if(write(fh, buffer,(unsigned)ftbl[fn].recsize)==ERR)
{
kaerror = 7; /* Write Error */
return(ERR);
}
return(OK);
}
write_upd(int fn, void *buffer)
{
return(write_rec(fn, buffer));
}
/** -----------------------------------------------------------------
** RDELETE - Delete a record in a key access file by record number.
** The record must have previously been read and rec # obtained
** ----------------------------------------------------------------- */
rdelete(int fn, long delrec)
{
long hblk;
int brec;
char * hp;
if(ftbl[fn].handle == FCLOSED || fn < 0 || fn >= KEYFILES)
{
kaerror = 4; /* File not open */
return(ERR);
}
if(rec > ftbl[fn].records || rec < 0)
{
kaerror = 13; /* Beyond File Limit */
return(ERR);
}
rec = delrec;
hblk = (long)delrec / ftbl[fn].kpb; /* get the hash index block no. */
if(read_hblk(ftbl[fn].handle, hblk)==ERR) return(ERR); /* read it */
brec = rec-(hblk * ftbl[fn].kpb); /* Rec # offset into this block */
hp = hbuf + (brec * ftbl[fn].keysize); /* point to the record */
*hp = 01; /* Delete the Record */
if(write_hblk(ftbl[fn].handle, hblk)==ERR) return(ERR); /* Write it */
return(OK);
}
/** -----------------------------------------------------------------
** READ_SEQ - Read sequential. Reads next record based on rec.
** Esentially reads rec+1 for next available record.
** ----------------------------------------------------------------- */
read_seq(int fn, void *buffer)
{
long hblk;
int brec;
char *hp;
if(ftbl[fn].handle == FCLOSED || fn < 0 || fn >= KEYFILES)
{
kaerror = 4; /* File not open */
return(ERR);
}
key[0]=0; /* Null the key */
while(TRUE)
{
if(rec+1 > ftbl[fn].records) return(KAEOF); /* End of file */
rec++; /* increment record */
hblk = rec / ftbl[fn].kpb; /* get the hash index block no. */
if(read_hblk(ftbl[fn].handle, hblk)==ERR) return(ERR);
brec = rec-(hblk * ftbl[fn].kpb); /* Rec # offset into this block */
hp = hbuf + (brec * ftbl[fn].keysize); /* point to the record */
if(*hp > 2)
{
strcpy(key, hp); /* Copy the key into the key storage */
return(read_xrec(fn, buffer)); /* Read the record & return */
}
if(*hp == 0) /* NO more recs this block */
{
hblk++;
if(hblk >= ftbl[fn].hblocks) return(KAEOF); /* At EOF */
rec = (hblk * ftbl[fn].kpb)-1; /* Get beginning rec number -1 */
}
}
}
/** -----------------------------------------------------------------
** READ_HBLK - Read Hash Block to Hash Block Buffer
**
** 2.0 Modified to add key offset
** ----------------------------------------------------------------- */
read_hblk(int fh, long blkno)
{
kaerror = 8;
if(lseek(fh, ((long)blkno * HBLOCKSIZE)+KEYSTART, 0)==ERR) return(ERR);
return(read(fh, hbuf, (unsigned)HBLOCKSIZE));
}
/** -----------------------------------------------------------------
** WRITE_HBLK - Write Hash Block from Hash Block Buffer
**
** 2.0 Modified to add key offset
** ----------------------------------------------------------------- */
write_hblk(int fh, long blkno)
{
kaerror = 9;
if(lseek(fh, ((long)blkno * HBLOCKSIZE)+KEYSTART, 0)==ERR) return(ERR);
return(write(fh, hbuf, (unsigned)HBLOCKSIZE));
}
/** ------------------------------------------------------------------
** KHASH - Hash a key and return the hash block number
** ------------------------------------------------------------------ */
long khash(char *hkey, long blocks)
{
char *hp;
double hc;
long val;
hc = (double)blocks-1;
hp = hkey; /* Point to key for Hashing */
while (*hp) hc += *hp++ - 32;
val = (long)fmod(hc, (double)blocks);
return(val);
}
/**************************************************************************
* FILECOMMIT - Commit a file's changes etc to disk. Flush.
*************************************************************************/
void filecommit(int fnum)
{
union REGS regs;
int rc, ec;
regs.h.ah = 0x68; /* Call to Flush */
regs.x.bx = ftbl[fnum].handle; /* Give the file's handle */
intdos(®s, ®s);
rc = regs.x.cflag;
if(rc != 0) ec = _doserrno;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -