<?php
/**
 * mongo cache
 * @copyright reginx.com
 * $Id: mongo.cache.php 108 2013-02-21 15:47:52Z reginx $
 */
class mongo_cache{

    /**
     * 当前连接的 Server ID
     *
     * @var unknown_type
     */
    private $_serverid = null;

    /**
     * mongo 对象
     *
     * @var unknown_type
     */
    private $_mongo = null;

    /**
     * 配置信息
     *
     * @var unknown_type
     */
    private $_conf = array();

    /**
     * 当前配置信息
     *
     * @var unknown_type
     */
    private $_serv = array();

    /**
     * MongoDB 对象
     *
     * @var unknown_type
     */
    private $_db = null;

    /**
     * 架构函数
     *
     * @param unknown_type $opts
     */
    public function __construct($opts){
        $this->_conf = &$opts;
        $this->_serverid = mt_rand(0, count($this->_conf) - 1);
        $this->_serv = $opts[$this->_serverid];
        if(!class_exists('Mongo', false)){
            core::error(core::L('no-support', 'Mongo'));
        }
        if(empty($this->_mongo)){
            try{
                $this->_mongo = new Mongo("mongodb://{$this->_serv['user']}:{$this->_serv['passwd']}@{$this->_serv['host']}:{$this->_serv['port']}", array(
                        'persist' => 'reginx',
                        'timeout' => 30
                ));
            }catch(Exception $e){
                core::error(core::L('conn-fail', 'Mongo Server'));
            }
        }
        $this->_db = $this->_mongo->selectDB($this->_serv['db']);
    }

    /**
     * 存入值
     *
     * @param unknown_type $key
     * @param unknown_type $val
     * @param unknown_type $ttl
     * @param unknown_type $pre
     */
    public function set($key, $val, $ttl = 0){
        $key = $this->_serv['pre'] . strtolower($key);
        $collect = $this->_db->selectCollection($this->getcol($key));
        $record = $collect->findOne(array(
                'key' => $key
        ));
        $ttl = $ttl > 1 ? REQUEST_TIME + $ttl : 0;
        if(empty($record)){
            $collect->insert(array(
                    'key' => $key,
                    'data' => $val,
                    'ttl' => $ttl
            ));
        }else{
            $collect->update(array(
                    'key' => $key
            ), array(
                    '$set' => array(
                            'data' => $val,
                            'ttl' => $ttl
                    )
            ));
        }
        cache_extra::count(0);
    }

    /**
     * 获取collection 名称
     *
     * @param unknown_type $key
     * @return unknown
     */
    private function getcol($key){
        $ret = 'reginx';
        if(($pos = strpos($key, '@')) !== false){
            $ret = substr($key, 0, $pos);
        }
        return $ret;
    }

    /**
     * 获取值
     *
     * @param unknown_type $key
     * @return unknown
     */
    public function get($key){
        $ret = null;
        $key = $this->_serv['pre'] . strtolower($key);
        $collect = $this->_db->selectCollection($this->getcol($key));
        $record = $collect->findOne(array(
                'key' => $key
        ));
        if($record['ttl'] <= 1 || REQUEST_TIME < $record['ttl']){
            $ret = $record['data'];
        }
        cache_extra::count(1);
        return $ret;
    }

    /**
     * 清除缓存数据
     *
     * @param unknown_type $key
     */
    public function clear($key = null){
        $key = $this->_serv['pre'] . $key;
        if($key === null){
            $cols = $this->_db->listCollections();
            foreach($cols as $v){
                $v->drop();
            }
        }else{
            $this->_db->selectCollection($this->getcol($key))->remove(array(
                    'key' => $key
            ));
        }
    }

    /**
     * clear 别名方法
     *
     * @param unknown_type $key
     * @param unknown_type $pre
     * @return unknown
     */
    public function delete($key){
        return $this->clear($key);
    }


    /**
     * 运行状态统计
     */
    public function stat(){
        $ret  = array();
        $stat = $this->_db->command(array('dbStats' => 1));
        $ret[] = array('数据库名' , $stat['db']);
        $ret[] = array('集合总数' , $stat['collections']);
        $ret[] = array('缓存对象' , $stat['objects']);
        $ret[] = array('数据总量' , sprintf('%.2f K' , $stat['dataSize']  / 1024));
        $ret[] = array('占用空间' , sprintf('%.2f K' , $stat['storageSize']  / 1024));
        return $ret;
    }
    
    /**
     * 析构函数
     */
    public function __destruct(){
        if($this->_mongo && !$this->_conf['p']){
            $this->_mongo->close();
        }
    }
}
?>