[RC5] DES 2 (in preparation of)

Sanford Olson sanford at msn.fullfeed.com
Fri Jan 9 11:45:30 EST 1998


At 06:43 AM 1/9/98 -0500, Colin L. Hildinger wrote:
>FIFO would be one way but I think that would
>cause problems with people using it on a shared network directory since
>it would no longer just be a stack.  If it was FIFO then new blocks
>would have to be added at the beginning of the buff-out file or blocks
>for checking would have to be taken from the beginning.  I could see
>this causing problems if there were many clients sharing it and it was
>updating from the servers, etc.  Anyone else got any other ideas for
>how the client could solve it w/o people manually cleaning out old
>buff-in files by one of the methods discussed here earlier?


Making the clients FIFO is a trivial programming exercise.  Both a queue
(FIFO) and a stack (LIFO) are linked lists.  However, a queue requires two
list pointers while a stack only needs one.  Also, to keep a queue from
constantly adding to the end of the file, garbage collection is needed (a
reusable or deleted record list).


The code for FIFO would look something like this:


typedef unsigned short RecordNumber;  //0 to 65535
typdef char[4] VersionString;         // Format Vx.x

struct FileHeader {
  VersionString Version;        //File's structure version number
  RecordNumber  nRecords;       //Total records in file
  RecordNumber  QHead;          //Front of queue
  RecordNumber  QTail;          //Back of queue
  RecordNumber  nQueuedRecords; //For quick access to number of records in
queue
  RecordNumber  ReuseHead;      //Head of list of reusable records
  };

struct DataRecord {
  RC5Type      RC5;            //RC5 stuff (block #, client info, etc)
  RecordNumber Next;           //Next record in list
  };


void AddRecordToEndOfQueue(RC5Type* RC5) {
   FileHeader   FH;
   DataRecord   DR;
   RecordNumber NewRN;

   //Lock file and load file header
   LockFile;    //Lock file for exclusive access
   ReadFileHeader(&FH);

   //Compute the Record Number of the new record
   if (FH.ReuseHead == 0) {
      //Reuse list is empty, add to end of file
      FH.nRecords++;
      NewRN = FH.nRecords;
      }
   else {
      NewRN = FH.ReuseHead;
      ReadRecord(NewRN,&DR);
      FH.ReuseHead = DR.Next;
      }

   //Copy RC5 data into record buffer and write record
   memcpy(&DR.RC5,RC5,sizeof(DR.RC5));
   DR.Next = 0;
   WriteRecord(NewRN,&DR);

   //Add Record into Queue's linked list
   if (FH.QTail == 0) FH.QTail = FH.QHead = NewRN;
   else {
      ReadRecord(FH.QTail,&DR);
      DR.Next = NewRN;
      WriteRecord(FH.QTail,&DR);
      FH.QTail = NewRN;
      }
   FH.nQueuedRecords++;

   //We're done - write FileHeader back and unlock file
   WriteFileHeader(&FH);
   UnlockFile;
   }


BOOL GetNextRecordFromQueue(RC5Type *RC5) {
   FileHeader   FH;
   DataRecord   DR;
   RecordNumber RN;

   //Lock file and load file header
   LockFile;    //Lock file for exclusive access
   ReadFileHeader(&FH);

   //Check for empty queue
   if (FH.QHead == 0) return FALSE;

   //Read record and copy to RC5 param
   RN = FH.QHead;
   ReadRecord(RN,&DR);
   memcpy(RC5,&DR.RC5,sizeof(DR.RC5));

   //Remove record from Queue linked list
   FH.QHead = DR.Next;
   if (FH.QHead == 0) FH.QTail = 0;
   FH.nQueuedRecords--;

   //Add record to reuse linked list
   DR.Next = FH.ReuseHead;
   FH.ReuseHead = RN;
   WriteRecord(RN,&DR);

   //We're done - write FileHeader back and unlock file
   WriteFileHeader(&FH);
   UnlockFile;

   return TRUE;
   }
--
To unsubcribe, send 'unsubscribe rc5' to majordomo at llamas.net
rc5-digest subscribers replace rc5 with rc5-digest



More information about the rc5 mailing list