📄 class_basic_record_file.php
字号:
<?php
// ver 1.0 2002/08/09,2002/12/31
define('NULLPTR',0);
define('PTR_SIZE',8);
define('PTRFIELD_SIZE',PTR_SIZE*3);
define('HEADER_SIZE',PTR_SIZE*8);
// PtrSeg: ptrNextSeg(8),[ptrPrev(8),ptrNext(8)]
// Header: magic(4),recSize(8),recNum(8),segNum(8),ptrHead(8),ptrTail(8),ptrFree(8),resv(12)
class CBasicRecordFile {
var $_fp=NULLPTR, $_magic, $_recSize, $_recNum, $_segNum, $_ptrHead, $_ptrTail, $_ptrFree;
var $_curId=NULLPTR, $_ptrPrev=NULLPTR, $_ptrNext=NULLPTR;
var $recordBuffer;
function _explodeRecord($a_line){}
function _composeRecord($a_line){}
function _compareRecord($a_key){/*return true/false*/}
function _readHeader(){
fseek($this->_fp, 0); $buf=fread($this->_fp, HEADER_SIZE);
list($this->_magic, $this->_recSize, $this->_recNum, $this->_segNum,
$this->_ptrHead, $this->_ptrTail, $this->_ptrFree)=explode('|',$buf);
}
function _writeHeader(){
$buf='PKY1|'.$this->_recSize.'|'.$this->_recNum.'|'.$this->_segNum
.'|'.$this->_ptrHead.'|'.$this->_ptrTail.'|'.$this->_ptrFree.'|';
fseek($this->_fp, 0); fwrite($this->_fp, str_pad($buf,HEADER_SIZE), HEADER_SIZE);
}
function _readPointer($a_recId, $a_offset, $a_ptrVal){
fseek($this->_fp, $a_recId*$this->_recSize+HEADER_SIZE+$a_offset*PTR_SIZE);
$a_ptrVal=fread($this->_fp, PTR_SIZE);
}
function _writePointer($a_recId, $a_offset, $a_ptrVal){
fseek($this->_fp, $a_recId*$this->_recSize+HEADER_SIZE+$a_offset*PTR_SIZE);
fwrite($this->_fp, str_pad($a_ptrVal,PTR_SIZE,' ',STR_PAD_LEFT), PTR_SIZE);
}
function _allocSegment(){
if($this->_ptrFree > NULLPTR){
$ptrNew=$this->_ptrFree;
$this->_readPointer($ptrNew, 0, &$this->_ptrFree);
}else{
$ptrNew=$this->_segNum+1;
$this->_writePointer($ptrNew, 0, NULLPTR);
fwrite($this->_fp, str_repeat(' ',$this->_recSize));
}
$this->_segNum++;
return $ptrNew;
}
function _allocSegmentList($a_size){
$size=$this->_recSize - PTR_SIZE;
$rest=$a_size; $recId=NULLPTR;
while($rest > 0) {
$segId=$this->_allocSegment();
$this->_writePointer($segId, 0, $recId);
$recId=$segId; $rest-=$size;
}
return $recId;
}
function _reallocSegmentList($a_idx, $a_size){
$size=$this->_recSize - PTR_SIZE;
$ptrSeg=$a_idx; $rest=$a_size;
do{
$lastSeg=$ptrSeg; $rest-=$size;
$this->_readPointer($lastSeg, 0, &$ptrSeg);
}while($rest > 0 && $ptrSeg > NULLPTR);
if($rest>0){
$ptrSeg=$this->_allocSegmentList($rest);
$this->_writePointer($lastSeg, 0, $ptrSeg);
}elseif($ptrSeg > NULLPTR){
$this->_freeSegmentList($ptrSeg);
$this->_writePointer($lastSeg, 0, NULLPTR);
}
return $a_idx;
}
function _freeSegmentList($a_idx){
$ptrSeg=$a_idx;
do {
$lastSeg=$ptrSeg; $this->_segNum--;
$this->_readPointer($lastSeg, 0, &$ptrSeg);
}while($ptrSeg > NULLPTR);
$this->_writePointer($lastSeg, 0, $this->_ptrFree);
$this->_ptrFree=$a_idx;
}
function _readRecordPointer($a_recId, $a_ptrPrev, $a_ptrNext){
fseek($this->_fp, $a_recId * $this->_recSize + HEADER_SIZE);
$buf=fread($this->_fp, PTRFIELD_SIZE);
$a_ptrPrev=substr($buf,PTR_SIZE,PTR_SIZE);
$a_ptrNext=substr($buf,PTR_SIZE*2);
}
function _readRecord($a_recId, $a_ptrPrev, $a_ptrNext, $a_buf){
$buf=""; $ptrSeg=$a_recId;
do {
fseek($this->_fp, $ptrSeg * $this->_recSize + HEADER_SIZE);
$segBuf=fread($this->_fp, $this->_recSize);
$ptrSeg=substr($segBuf,0,PTR_SIZE);
$buf.=substr($segBuf,PTR_SIZE);
} while ($ptrSeg > NULLPTR);
if($buf[PTR_SIZE*2]=="\x07"){
$a_ptrPrev=substr($buf,0,PTR_SIZE);
$a_ptrNext=substr($buf,PTR_SIZE,PTR_SIZE);
$a_buf=substr($buf,PTR_SIZE*2+1);
return true;
}else{
return false;
}
}
function _writeRecord($a_recId, $a_ptrPrev, $a_ptrNext, $a_buf){
$buf=str_pad($a_ptrPrev,PTR_SIZE,' ',STR_PAD_LEFT)
.str_pad($a_ptrNext,PTR_SIZE,' ',STR_PAD_LEFT)."\x07".$a_buf;
$this->_reallocSegmentList($a_recId, strlen($buf));
$ptrSeg=$a_recId;
do{
$tmpbuf=substr($buf,0,$this->_recSize-PTR_SIZE);
$buf=substr($buf,$this->_recSize-PTR_SIZE);
if(!$buf){$tmpbuf=str_pad($tmpbuf,$this->_recSize-PTR_SIZE);}
fseek($this->_fp, $ptrSeg * $this->_recSize + HEADER_SIZE + PTR_SIZE);
fwrite($this->_fp, $tmpbuf, $this->_recSize-PTR_SIZE);
$this->_readPointer($ptrSeg, 0, &$ptrSeg);
}while ($buf && $ptrSeg > NULLPTR);
}
function _destroyRecord($a_recId){
$buf=str_pad(NULLPTR,PTR_SIZE).str_pad(NULLPTR,PTR_SIZE)."\x08";
fseek($this->_fp, $a_recId * $this->_recSize + HEADER_SIZE + PTR_SIZE);
fwrite($this->_fp, $buf, $this->_recSize-PTR_SIZE);
}
function _validateRecord($a_recId){
if($a_recId <= NULLPTR){return false;}
fseek($this->_fp, $a_recId*$this->_recSize + HEADER_SIZE + PTRFIELD_SIZE);
$flag=fread($this->_fp, 1);
return ($flag == "\x07");
}
function readMemo(){
fseek($this->_fp, HEADER_SIZE);
return fread($this->_fp, $this->_recSize);
}
function writeMemo($a_buf){
fseek($this->_fp, HEADER_SIZE);
return fwrite($this->_fp,
str_pad($a_buf,$this->_recSize), $this->_recSize);
}
function open($a_filename){
if(!($this->_fp=fopen($a_filename, "r+b"))){return false;}
$this->_readHeader();
return ($this->_magic=='PKY1');
}
function close(){
fclose($this->_fp);
}
function getRecordCount() {return (integer)$this->_recNum;}
function getAbsolutePosition() {return (integer)$this->_curId;}
function setAbsolutePosition($a_idx) {
if(!$this->_validateRecord($a_idx)){return false;}
if($this->_readRecord($a_idx, &$this->_ptrPrev, &$this->_ptrNext, &$this->recordBuffer)){
$this->_curId=$a_idx;
$this->_explodeRecord(&$this->recordBuffer);
return true;
}else{
return false;
}
}
function moveTo($a_offset, $a_forward=true) {
$tmpIdx=($a_forward) ? $this->_ptrHead : $this->_ptrTail;
$count=0;
while(($count<$a_offset)&&($tmpIdx>NULLPTR)){
$this->_readRecordPointer($tmpIdx,&$tmpPrev,&$tmpNext);
$tmpIdx=($a_forward) ? $tmpNext : $tmpPrev;
$count++;
}
return $this->setAbsolutePosition($tmpIdx);
}
function moveFirst(){return $this->setAbsolutePosition($this->_ptrHead);}
function moveLast(){return $this->setAbsolutePosition($this->_ptrTail);}
function moveNext(){return $this->setAbsolutePosition($this->_ptrNext);}
function movePrev(){return $this->setAbsolutePosition($this->_ptrPrev);}
function find($a_key) {
$flag=$this->moveFirst();
while ($flag){
if($this->_compareRecord(&$a_key)){return true;}
$flag=$this->moveNext();
}
return false;
}
function update() {
flock($this->_fp, 2);
$this->_readHeader();
if(!$this->_validateRecord($this->_curId)){
flock($this->_fp, 3); return false;
}
$this->_composeRecord(&$this->recordBuffer);
$this->_writeRecord(&$this->_curId, &$this->_ptrPrev, &$this->_ptrNext, &$this->recordBuffer);
$this->_writeHeader();
fflush($this->_fp);
flock($this->_fp, 3);
return true;
}
function appendNew() {
flock($this->_fp, 2);
$this->_readHeader();
$ptrNew=$this->_allocSegmentList(1);
if($this->_ptrTail > NULLPTR){
$this->_ptrPrev=$this->_ptrTail;
$this->_writePointer($this->_ptrTail, 2, $ptrNew);
$this->_ptrTail=$ptrNew;
}else{
$this->_ptrPrev= NULLPTR;
$this->_ptrTail=$this->_ptrHead=$ptrNew;
}
$this->_ptrNext= NULLPTR;
$this->_curId=$ptrNew;
$this->_writeRecord($ptrNew, $this->_ptrPrev, $this->_ptrNext, "");
$this->_recNum++;
$this->_writeHeader();
fflush($this->_fp);
flock($this->_fp, 3);
return $this->_curId;
}
function delete() {
flock($this->_fp, 2);
$this->_readHeader();
if(!$this->_validateRecord($this->_curId)){
flock($this->_fp, 3); return false;
}
if($this->_ptrPrev > NULLPTR){
$this->_writePointer($this->_ptrPrev, 2, $this->_ptrNext);
}else{
$this->_ptrHead=$this->_ptrNext;
}
if($this->_ptrNext > NULLPTR){
$this->_writePointer($this->_ptrNext, 1, $this->_ptrPrev);
}else{
$this->_ptrTail=$this->_ptrPrev;
}
$this->_destroyRecord($this->_curId);
$this->_freeSegmentList($this->_curId);
$this->_recNum--;
$this->_writeHeader();
fflush($this->_fp);
flock($this->_fp, 3);
return true;
}
function createFile($a_filename, $a_recsize){
$this->_fp=fopen($a_filename,"wb");
$this->_recSize=($a_recsize>PTRFIELD_SIZE) ? $a_recsize : PTRFIELD_SIZE+1;
$this->_recNum=$this->_segNum=0;
$this->_ptrHead=$this->_ptrTail=$this->_ptrFree=NULLPTR;
$this->_writeHeader();
fwrite($this->_fp, str_repeat('*',$this->_recSize));
fclose($this->_fp);
return true;
}
function destroyFile($a_filename){
if(!is_file($a_filename)){return false;}
return unlink($a_filename);
}
}
?>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -