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 + -
显示快捷键?