PHP使用hash算法實現一個娛樂平臺出租實例

咱們這次主要是使用PHP語言,娛樂平臺出租《企娥21717 93408》結合hash算法,來實現一個簡單的數據庫實例,它主要有四個功能,連接數據庫,查詢操作,插入操作,刪除操作,關閉數據庫連接操作,其它的大家可以後期補充完善下,咱廢話不多說,先來看代碼:
<?php
header('Content-type:text/html;charset=utf-8');

define('DB_INSERT',1);
define('DB_REPLACE',2);
define('DB_STORE',3);
define('DB_BUCKET_SIZE',262114);
define('DB_KEY_SIZE',128);
define('DB_INDEX_SIZE',DB_KEY_SIZE+12);
define('DB_KEY_EXISTS',1);
define('DB_FAILURE',-1);
define('DB_SUCCESS',0);

class DB{
private $idx_fp;
private $dat_fp;
private $closed;

public function open($path_name)
{
    $idx_path = $path_name.".idx";
    $dat_path = $path_name.".dat";

    if (!file_exists($idx_path)) {
        $init = true;
        $mode = 'w+b';
    }else{
        $init = false;
        $mode = 'r+b';
    }

    $this->idx_fp = fopen($idx_path,$mode);
    if($init){
        $elem = pack('L',0x00000000);
        for ($i=0;$i<DB_BUCKET_SIZE;$i++) {
            fwrite($this->idx_fp,$elem,4);
        }
    }

    $this->dat_fp = fopen($dat_path,$mode);
    if(!file_exists($dat_path)) {
        return DB_FAILURE;
    }
    if(!$this->dat_fp) {
        return DB_FAILURE;
    }
    return DB_SUCCESS;
}

private function _hash($str)
{
    $str = substr(md5($str),0,8);
    $hash = 0;
    for ($i=0;$i<8;$i++) {
        $hash += 33*$hash+ord($str[$i]);
    }
    return $hash&0x7FFFFFFF;
}

public function fetch($key)
{
    $offset = ($this->_hash($key)%DB_BUCKET_SIZE)*4;
    fseek($this->idx_fp,$offset,SEEK_SET);
    $pos = unpack('L',fread($this->idx_fp,4));
    $pos = $pos[1];
    $found = false;
    while ($pos) {
        fseek($this->idx_fp,$pos,SEEK_SET);
        $block = fread($this->idx_fp,DB_INDEX_SIZE);
        $cp_key = substr($block,4,DB_KEY_SIZE);
        if (!strncmp($key,$cp_key,strlen($key))) {
            $data_off = unpack('L',substr($block,DB_KEY_SIZE+4,4));
            $data_off = $data_off[1];
            $data_len = unpack('L',substr($block,DB_KEY_SIZE+8,4));
            $data_len = $data_len[1];
            $found = true;
            break;
        }

        $pos = unpack('L',substr($block,0,4));
        $pos = $pos[1];
    }

    if(!$found) {
        return null;
    }

    fseek($this->dat_fp,$data_off,SEEK_SET);
    $data = fread($this->dat_fp,$data_len);
    return $data;
}

public function insert($key,$data)
{
    $offset = ($this->_hash($key)%DB_BUCKET_SIZE)*4;
    $idx_off = fstat($this->idx_fp);
    $idx_off = intval($idx_off['size']);
    $dat_off = fstat($this->dat_fp);
    $dat_off = intval($dat_off['size']);
    $key_len = strlen($key);
    if($key_len > DB_KEY_SIZE) {
        return DB_FAILURE;
    }

    $block = pack('L',0x00000000);
    $block .= $key;
    $space = DB_KEY_SIZE-$key_len;
    for ($i=0;$i<$space;$i++) {
        $block .= pack('C',0x00);
    }
    $block .= pack('L',$dat_off);
    $block .= pack('L',strlen($data));

    fseek($this->idx_fp,$offset,SEEK_SET);
    $pos = unpack('L',fread($this->idx_fp,4));
    $pos = $pos[1];

    if ($pos == 0) {
        fseek($this->idx_fp,$offset,SEEK_SET);
        fwrite($this->idx_fp,pack('L',$idx_off),4);
        fseek($this->idx_fp,0,SEEK_END);
        fwrite($this->idx_fp,$block,DB_INDEX_SIZE);
        fseek($this->dat_fp,0,SEEK_END);
        fwrite($this->dat_fp,$data,strlen($data));
        return DB_SUCCESS;
    }

    $found = false;
    while ($pos) {
        fseek($this->idx_fp,$pos,SEEK_SET);
        $tmp_block = fread($this->idx_fp,DB_INDEX_SIZE);
        $cp_key = substr($tmp_block,4,DB_KEY_SIZE);
        if(!strncmp($key,$cp_key,strlen($key))) {
            $data_off = unpack('L',substr($tmp_block,DB_KEY_SIZE+4,4));
            $data_off = $data_off[1];
            $data_len = unpack('L',substr($tmp_block,DB_KEY_SIZE+8,4));
            $data_len = $data_len[1];
            $found = true;
            break;
        }

        $prev = $pos;
        $pos = unpack('L',substr($tmp_block,0,4));
        $pos = $pos[1];
    }

    if ($found) {
        return DB_KEY_EXISTS;
    }

    fseek($this->idx_fp,$prev,SEEK_SET);
    fwrite($this->idx_fp,pack('L',$idx_off),4);
    fseek($this->idx_fp,0,SEEK_END);
    fwrite($this->idx_fp,$block,DB_INDEX_SIZE);
    fseek($this->dat_fp,0,SEEK_END);
    fwrite($this->dat_fp,$data,strlen($data));
    return DB_SUCCESS;
}

public function delete($key)
{
    $offset = ($this->_hash($key)%DB_BUCKET_SIZE)*4;
    fseek($this->idx_fp,$offset,SEEK_SET);
    $head = unpack('L',fread($this->idx_fp,4));
    $head = $head[1];
    $curr = $head;
    $prev = 0;

    while ($curr) {
        fseek($this->idx_fp,$curr,SEEK_SET);
        $block = fread($this->idx_fp,DB_INDEX_SIZE);
        $next = unpack('L',substr($block,0,4));
        $next = $next[1];
        $cp_key = substr($block,4,DB_KEY_SIZE);
        if(!strncmp($key,$cp_key,strlen($key))) {
            $found = true;
            break;
        }

        $prev = $curr;
        $curr = $next;
    }

    if(!$found){
        return DB_FAILURE;
    }

    if ($prev == 0) {
        fseek($this->idx_fp,$offset,SEEK_SET);
        fwrite($this->idx_fp,pack('L',$next),4);
    }else{
        fseek($this->idx_fp,$prev,SEEK_SET);
        fwrite($this->idx_fp,pack('L',$next),4);
    }

    return DB_SUCCESS;
}

public function close()
{
    if (!$this->closed) {
        fclose($this->idx_fp);
        fclose($this->dat_fp);
        $this->closed = true;
    }
}

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章