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

📄 数据库算法(一)代码列表.c

📁 数据库算法源代码
💻 C
字号:
数据库算法(一)代码列表
列表2:TaaRecordStream类的接口
type
	PaaRSHeaderRec = ^TaaRSHeaderRec;
	TaaRSHeaderRec = packed record
		hrSignature 		: longint;
		hrHeaderLen 		: longint;
		hrRecorderLen	: longint;
		hrCount			: longint; { the number of active records }
		hrCapacity		: longint; { the number of all records }
		hr1stDelRec		: longint;
	end;
type
	TaaRecordStream = class
		private
			FFileStrm	: TFileStream;
			FHeader		: PaaRSHeaderRec;
			FStream		: TSream;
			FRecLen		: integer;
		protected
			procedure 	rsCreateNew;
			procedure		rsOpenExisting;
			function		rsCalcRecordOffset( aRecNum : integer ) : longint;
			procedure		rsReadStream( var aRec ; aRecLen : integer );
			procedure		rsSeekStream( aOffset : longint );
			procedure		rsWriteStream( const aRec ; aRecLen : integer );
	public
			constructor	Create( aStream : TStream; aCreateNew : boolean ; 
aRecLen : integer );
			constructor	CreateFile( const aFileName : string ; aCreateNew : boolean ;
				aRecLen : integer );
			destructor 	Destroy : override;
			function		Add( const aRec ) : integer;
			procedure 	Delete( aRecNum : integer );
			function 		Read( aRecNum : integer : var aRec ) : Boolean;
			procedure 	Write( aRecNum : integer ; var aRec );
	end;

列表3:TaaRecordStream类的实现
const
	cRSSignature = $1A524454;
	cActiveRecord = -2;
	cEndOfDeletedChain = -1;

constructor TaaRecordStream.Create( aStream : TSream ;
		aCreateNew : boolean; aRecLen : integer );
begin
	{create the ancestor}
	inherited Create;
	{save the parameters}
	FStream := aStream;
	FRecLen := aRecLen;
	{if we should create a new record stream . do so}
	if aCreateNew then begin
		Assert(aRecLen > 0 , 'TaaRecordStream.Create: ' + 
			'the record length must be greater than zero' );
		rsCreateNew;
	end else
		esOpenExisting;
end;

constructor TaarecordStream.CreateFile( const aFileName:string; 
	aCreateNew : boolean; aRecLen : integer );
begin
	{if needed , create the file}
	if aCreateNew then begin
		FFileStrm := TFileStream.Create( aFileName , fmCreate );
		FFileStrm.Free;
		FFileStrm := nil;
	end;
	{create the file stream}
	FFileStrm := TFileStream.Create( aFileName , 
		fmOpenReadWrite + fmShareDenyWrite );
	{call the other construcor to finish off}
	Create(FFileStrm , aCreateNew , aRecLen );
end;

destructor TaaRecordStream.Destroy;
begin
	{if we created a file stream , close it}
	if( FFileStrm <> nil ) then
		FFileStrm.Free;
	{frre the header record}
	if( FHeader <> nil ) then
		FrreMem( FHeader , Fheader^.hrHeaderLen );
	{finally destroy the ancestor}
	inherited Destroy;
end;

function TaaRecordStream.Add( const aRec ) : integer;
var 
	TempRec : PChar;
	Offset 	: longint;
begin
	{if the deleted record chain is empty , we'll be adding the 
		record to the end of the stream; calculate its offset}
	if (FHeader^.hrstDelRec = cEndOfDeletedChain ) then begin
		Result := FHeader^.hrCapacity;
		inc(FHeader^.hrCapacity);
		Offset := rsCalcRecordOffset(Result);
	end else begin
		{otherwise , use the first deleted record , upsate the 
			header record's deleted record chain to start at 
			the next deleted record}
		Result := FHeader^.hr1stDelREc;
		Offset := rsCalcRecordOffset(Result);
		rsSeekStream(Offset);
		rsReadStream(FHeader^.hr1stDelRec , sizeof(longint));
	end;
	{seek to the record offset and write the new record}
	rsSeekStream(Offset);
	GetMem( TempRec , FRecLen + sizeof(longint));
	try
		PLongint(TempRec)^ := cActiveRecord;
		Move(aRec , TempRec[sizeof(longint)],FRecLen);
		rsWriteStream(TempRec^,FRecLen + sizeof(longint));
	finally
		FreeMen(TempRec , FRecLen + sizeof(longint));
	end;
	{we have one more active record}
	inc(FHeader^.hrCount);
	{now update the header record}
	rsSeekStream(0);
	rsWriteStream(FHeader^.sizeof(TaaRSHeaderRec));
end;

procedure TaaRecordStream.Delete(aRecNum : integer);
var
	DelLink : longint;
	Offset  : longint;
begin
	{calculate the record offset}
	Offset := rsCalcRecordOffset(aRecNum);
	{check to see that the record is not already deleted}
	rsSeekStream(Offset);
	rsReadStream(DelLink,sizeof(longint));
	if (DelLink <> cActiveRecord) then
			raise Exception.Create(
				'TaaRecordStream.Delete record already deleted');
	{write the first deleted record number to the first 4 bytes of the 
		record we're deleting}
	rsSeekStream(Offset);
	rsWriteStream(FHeader^.hr1stDelRec , sizeof(longint));
	{update the deleted record chain to start at the record we're 
	deleting}

	FHeader^.hr1stDelRec := aRecNum;
	{we have one less record}
	dec(FHeader^.hrCount);
	{now update the header record}
	rsSeekStream(0);
	rsWriteStream(FHeader^,sizeof(TaaRSHeaderRec));
end;

function TaaRecordStream.Read(aRecNum : integer; var aRec):boolean;
var
	TempRec : PChar;
	Action	: integer;
	Offset	: longint;
begin
	{calculate the record offset}
	offset := rsCalcRecordOffset(aRecNum);
	{get a temporary buffer in order to read entire record}
	ActLen := FRecLen + sizeof(longint);
	GetMem( TempRec , ActLen );
	try
		{seek and read the entire record}
		rsSeekStream(Offset);
		rsReadStream(TempRec^ , ActLen);
		{if it's deleted , return flase}
		if (PLongint(TempRed)^ <> cActiveRecord ) then
			result := false;
		{otherwise transfer the record data}
		else begin
			Result := true;
			Move(TempRec[sizeof(longint)] , aRec , FRecLen );
		end;
		{finally free our temporary buffer}
		finally
			FreeMem(TempRec , ActLEn);
	end;
end;

function TaaRecordStream.rsCalcRecordOffset( aRecNum : integer ):longint;
begin
	{first verify that the record number is in range}
	if (aRecNum < 0) or (aRecNum > FHeader^.hrCapacity) then
		raise Exception.Create('TaaRecordStream.rsCalcRecordOffset :'
		+ 'record number is out of range' );
	{second ,calculate the offset}
	Result := FHeader^.hrHeaderLen + (aRecNum*(FRecLen + sizeof(longint)));
end;

procedure TaaRecordStream.rsCreateNew;
var
	HeaderSize : integer;
begin
	{calculate the size of the header}
	HeaderSize := FRecLen + sizeof(longint);
	if (HeaderSize < sizeof(TaaRSHeaderRec)) then
		HeaderSize := sizeof(TaaRSHeaderRec);
	{allocate a header record}
	FHeader := AllocMem(HeaderSize);
	{initialize the header}
	with FHeader^ do begin
		hrSinature := cRSSignature;
		hrHeaderLen:= HeaderSize;
		hrRecordLen := FRecLen;
		hrCount := 0;
		hrCapacity := 0;
		hr1stDelRec := cEndOfDeletedChain;
		end;
	{now update the header record}
	rsSeekStream(0);
	rsWriteStream(FHeader^ , FHeader^.hrHeadLen);
end;

procedure TaaRecordStream.rsOpenExisting;
var
	StreamSize	  : longint;
	ExpectedSize  : longint;
	TempHeaderRec : longint;
begin
	{if the stream size is not at least the size of the
		header record , it can't be one of ours}
	StreamSize := FStream.Size;
	if (FStream.Size < sizeof(TaaRSHeaderRec)) then
		raise Exception.Create(
			'TaaRecordStream.rsOpenExisting: not a valid record '+
			'file/stream (too small error)');
		{read the header record}
	rsSeekStream(0);
	rsReadStream(TempHeaderRec , sizeof(TaaRSHeaderRec));
	{first sanity check: the signature and count}
	with TempHeaderRec do
		if (hrSignature <> cRSSignature) or
			(hrCount < 0) or (hrCount > hrCapacity) then
			raise Exception.Create(
			'TaaRecordStream.rsOpenExisting: not a valid ' +
			'record file/stream (header error)');
		{second sanity check: the size of file}
	with TempHeaderRec do begin
		ExpectedSize := hrHeaderLen + (hrCapacity*(hrRecordLen+sizeof(longint)));
		if (StreamSize <> ExpectedSize ) then
			raise Exception.Create(
				'TaaRecordStream.rsOpenExisting: not a valid '+
				'record file/stream (size error)');
		end;
	{allocate true header record , copy the data already read}
	FHeader := AllocMen( TempHeaderRec.hrHeaderLen );
	{set up the class fields}
	FRecLen := FHeader^.hrRecordLen;
end;

procedure TaaRecordStreamj.rsReadStream(var aRec; aRecLen : integer);
var
	ByteRead : longint;
begin
	ByteRead := FStream.Read(aRec,aRecLen);
	if(ByteRead <> aRecLen) then
		raise Exception.Create('TaaRecordStream.rsReadStream: '+
		'counld not read required record');
end;

procedure TaaRecordStream.rsSeekStream(aOffset : longint);
var 
	Offset : longint;
begin
		Offset := FStream.Seek(aOffset , soFromBeginning);
		if (Offset <> aOffset) then
			raise Exception.Creat('TaaRecordStream.rsSeekStream: '+
			'could not seek to required offset');
end;

procedure TaaRecordStream.rsWriteStream(const aRec ; aRecLen : integer);
var
	ByteWritten : longint;
begin
	ByteWritten := FStream.Write(aRec , aRecLEn);
	if (ByteWritten <> aRecLen ) then
		raise Exception.Create(
		'TaaRecordStream.rsWriteStream: '+
		'could not write required record');
end;

procedure TaaRecordStream.Write(aRecNum : integer ; var aRec);
var
	DelLink : longint;
	Offset  : longint;
begin
	{calculate the record offset}
	Offset := rsCalcRecordOffset(aRecNum);
	{check to see that the record is not deleted}
	rsSeekStream(Offset);
	rsReadStream(DelLink , sizeof(DelLink));
	if (DelLink <> cActiveRecord) then
		raise ExcePtion.Create('TaaRecordStream.Write: record is deleted and cannot be uptated');
	{update the record}
	rsWriteStream(aRec , FRecLEn);
end;

⌨️ 快捷键说明

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