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

📄 kafs.c

📁 一个可以索引和排序的文件系统
💻 C
📖 第 1 页 / 共 2 页
字号:
 ** ----------------------------------------------------------------- */
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(&regs, &regs);
   rc = regs.x.cflag;
   if(rc != 0) ec = _doserrno;

}

⌨️ 快捷键说明

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