file.php
来自「视频监控网络部分的协议ddns,的模块的实现代码,请大家大胆指正.」· PHP 代码 · 共 828 行 · 第 1/2 页
PHP
828 行
* @return mixed string on success, false on failure */ function nextkey() { if ($this->isReadable() && ($this->size() > 0) && next($this->_usedBlocks)) { return key($this->_usedBlocks); } else { return false; } } // }}} // {{{ getkeys() /** * Returns all keys in the database * * @access public * @return mixed array */ function getkeys() { if ($this->isReadable() && ($this->size() > 0)) { return array_keys($this->_usedBlocks); } else { return array(); } } // }}} // {{{ size() /** * Calculates the size of the database in number of keys * * @access public * @return int number of keys in the database */ function size() { if (is_array($this->_usedBlocks)) { return sizeof($this->_usedBlocks); } else { return 0; } } // }}} // {{{ insert($key, $value) /** * Inserts a new value at $key. Will not overwrite if the key/value pair * already exist * * @access public * @param string $key key to insert * @param string $value value to store * @return object PEAR_Error on failure */ function insert($key, $value) { if ($this->exists($key)) { return $this->raiseError(DBA_ERROR_ALREADY_EXISTS, NULL, NULL, 'key: '.$key); } else { return $this->replace($key, $value); } } // }}} // {{{ replace($key, $value) /** * Inserts a new value at key. If the key/value pair * already exist, overwrites the value * * @access public * @param $key string the key to insert * @param $val string the value to store * @return object PEAR_Error on failure */ function replace($key, $value) { // is the database in a usable state? if ($this->isWritable()) { // get how much space we need $vsize = strlen($value); if (!isset($this->_usedBlocks[$key])) { // the value is new $this->_writeNewBlock($key, $value, $vsize); } else { // the value is not new $size = $this->_usedBlocks[$key][DBA_SIMPLE_SIZE]; // is the value smaller or equal in size to its block size if ($size >= $vsize) { // move to the block's location in the data file $loc = $this->_usedBlocks[$key][DBA_SIMPLE_LOC]; fseek($this->_datFP, $loc); // write to the data file fwrite($this->_datFP, str_pad($value, $size), $size); // update internal indecies $this->_usedBlocks[$key][DBA_SIMPLE_VSIZE] = $vsize; $this->_writeIdxEntry($loc, $size, $vsize, $key); // the value is larger than its allocated space } else { // free this value's allocated block $this->_freeUsedBlock($key); $this->_writeNewBlock($key, $value, $vsize); } } } else { return $this->raiseError(DBA_ERROR_NOT_WRITEABLE); } } // }}} // {{{ _writeNewBlock($key, $value, $vsize) /** * Allocates a new block of at least $vsize and writes $key=>$val * to the database * * @access private * @param string $key * @param string $value * @param int $vsize */ function _writeNewBlock($key, $value, $vsize) { // is there is a sufficiently sized block free ? $loc = $this->_getFreeBlock($vsize); if ($loc !== false) { // update free block list $size = $this->_freeBlocks[$loc]; unset($this->_freeBlocks[$loc]); // move to the block's location in the data file fseek($this->_datFP, $loc, SEEK_SET); // write to the data file fwrite($this->_datFP, str_pad($value,$size), $size); $this->_usedBlocks[$key] = array($loc, $size, $vsize); $this->_writeIdxEntry($loc, $size, $vsize, $key); // there is not a sufficiently sized block free } else { // move to the end of the data file fseek($this ->_datFP, 0, SEEK_END); $loc = ftell($this->_datFP); // write to the data file $size = $vsize + ceil($vsize / 20); // make size 5% larger // add a useless "\n" to new values. This makes the data file // readable in any text editor. Useful when things go wrong :P fwrite($this->_datFP, str_pad($value, $size)."\n", $size+1); // update internal block lists $this->_usedBlocks[$key] = array($loc, $size, $vsize); $this->_writeIdxEntry($loc, $size, $vsize, $key); } } // }}} // {{{ _getFreeBlock($reqsize) /** * Returns a block location from the free list * * @access private * @param int $reqsize Requested size * @returns mixed location of free block, false if there are no free blocks */ function _getFreeBlock($reqsize) { // check if we have any blocks to choose from if (is_array($this->_freeBlocks)) { // iterate through the blocks in blockIndex to find // a free block foreach ($this->_freeBlocks as $loc=>$size) { if ($size >= $reqsize) { return $loc; } } } // no blocks available return false; } // }}} // {{{ _freeUsedBlock($key) /** * Places a used block on the free list, updates indicies accordingly * * @access private * @param string $key * @returns mixed */ function _freeUsedBlock($key) { $loc = $this->_usedBlocks[$key][DBA_SIMPLE_LOC]; $size = $this->_usedBlocks[$key][DBA_SIMPLE_SIZE]; unset($this->_usedBlocks[$key]); $this->_freeBlocks[$loc] = $size; $this->_writeIdxEntry($loc, $size); } // }}} // {{{ create($dbName) /** * Creates a new database file if one does not exist. If it already exists, * updates the last-updated timestamp on the database * * @access public * @param string $dbName the database to create * @return object PEAR_Error on failure */ function create($dbName) { if (!(@touch($dbName.'.dat') && @touch($dbName.'.idx'))) { return $this->raiseError('Could not create database: '.$dbName); } } // }}} // {{{ db_exists($dbName) /** * Indicates whether a database with given name exists * * @access public * @param string $dbName the database name to check for existence * @return boolean true if the database exists, false if it doesn't */ function db_exists($dbName) { return(file_exists($dbName.'.dat') && file_exists($dbName.'.idx')); } // }}} // {{{ db_drop($dbName) /** * Removes a database from existence * * @access public * @param string $dbName the database name to drop * @return object PEAR_Error on failure */ function db_drop($dbName) { if (DBA_Driver_File::db_exists($dbName)) { if (!unlink($dbName.'.dat') || !unlink($dbName.'.idx')) { return $this->raiseError(DBA_ERROR_CANNOT_DROP, NULL, NULL, 'dbname: '.$dbName); } } else { return $this->raiseError(DBA_ERROR_NOSUCHDB, NULL, NULL, 'dbname: '.$dbName); } } // }}} // {{{ drop($dbName) /** * Removes the last open database from existence * * @access public * @return object PEAR_Error on failure */ function drop() { $this->close(); return $this->db_drop($this->_dbName); } // }}} // {{{ exists($key) /** * Check whether key exists * * @access public * @param string $key * @return boolean true if the key exists, false if it doesn't */ function exists($key) { return($this->isOpen() && isset($this->_usedBlocks[$key])); } // }}} // {{{ sync() /** * Synchronizes an open database to disk * @access public */ function sync() { if ($this->isWritable()) { fflush($this->_datFP); fflush($this->_idxFP); } } // }}} // {{{ optimize() /** * Optimizes an open database * @access public */ function optimize() { if ($this->isWritable()) { $this->_writeIdx(); } } // }}} // {{{ _readIdx() /** * Reads the entries in an index file * Assumes that $this->_idxFP is valid and readable * @access private */ function _readIdx() { // clear out old data if a previous database was opened $this->_usedBlocks = array(); $this->_freeBlocks = array(); $usedBlocks = array(); // temporary used index $key = ''; // reset key while (fscanf($this->_idxFP, '%u|%u|%u|%s', $loc, $size, $vsize, $key)) { // is this an free block? if ($key == '') { // check if this block had been previously marked as used if (isset($usedBlocks[$loc])) { unset($this->_usedBlocks[$usedBlocks[$loc]]); unset($usedBlocks[$loc]); } $this->_freeBlocks[$loc] = $size; } else { // check if this block had been previously marked as free if (isset($this->_freeBlocks[$loc])) { unset($this->_freeBlocks[$loc]); } $this->_usedBlocks[$key] = array($loc, $size, $vsize); $usedBlocks[$loc] = $key; } $key = ''; // reset key for the next iteration } } // }}} // {{{ _writeIdx() /** * Rewrites the index file, removing free entries * Assumes that $this->_idxFP is valid and writable * * @access private */ function _writeIdx() { // move the file pointer to the beginning; ftruncate does not do this fseek($this->_idxFP, 0); // clear the index ftruncate($this->_idxFP, 0); // write the free blocks if (isset($this->_freeBlocks)) { foreach ($this->_freeBlocks as $loc=>$size) { $this->_writeIdxEntry($loc,$size); } } // write the used blocks if (isset($this->_usedBlocks)) { foreach ($this->_usedBlocks as $key=>$block) { $this->_writeIdxEntry($block[DBA_SIMPLE_LOC], $block[DBA_SIMPLE_SIZE], $block[DBA_SIMPLE_VSIZE], $key); } } fflush($this->_idxFP); } // }}} // {{{ _writeIdxEntry($loc, $size, $vsize=NULL, $key=NULL) /** * Writes a used block entry to an index file * * @access private */ function _writeIdxEntry($loc, $size, $vsize=NULL, $key=NULL) { if (is_null($vsize)) { // write a free block entry fputs($this->_idxFP, "$loc|$size\n"); } else { // write a used block entry fputs($this->_idxFP, "$loc|$size|$vsize|$key\n"); } } // }}}}?>
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?