加载中…
个人资料
风之力量007
风之力量007
  • 博客等级:
  • 博客积分:0
  • 博客访问:17,670
  • 关注人气:8
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
相关博文
推荐博文
谁看过这篇博文
加载中…
正文 字体大小:

内存数据库简单实现

(2009-09-10 14:24:23)
标签:

杂谈

目前还没有日志,事务,以及永久化存储等复杂构建。

仅仅是一个雏形:
数据的同步并发,以及行锁的管理。

#pragma once

#ifdef _WIN32
#include <windows.h>
#else // linux
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <pthread.h>
#endif

#include <hash_map>
#include <string>
#include <sstream>

namespace MyMemDB
{
    namespace MyException // 异常
    {
        // 异常类
        class DBException
        {
            std::string errstr;
        public:
            DBException() { errstr = "DBException error!"; }
            DBException(std::string err) { errstr = err; }
            std::string GetErrorString() { return errstr; }
        };
    }

// 数据库基础表类
template<class Key, class Value>
    class Table
    {
    private:
        typedef Key KEY;
        typedef Value VALUE;
        stdext::hash_map<KEY,VALUE> records;
    public:
        int GetRowCount() { return records.size(); }
        void DeleteAll() { records.clear(); }
        const stdext::hash_map<KEY,VALUE>& GetAllValue(){ return records; }
    public:
        const VALUE&GetValue(KEY key)
        {
            typename stdext::hash_map<KEY,VALUE>::const_iterator itFind = records.find(key);
            if (itFind == records.end()) throw MyException::DBException("Key Not Found!");

            return (*itFind).second;
        }

        bool AddValue(KEY key, VALUE value)
        {
            typename stdext::hash_map<KEY,VALUE>::const_iterator itFind = records.find(key);
            if (itFind != records.end()) return false;

            records.insert( std::make_pair( key, value));

            return true;
        }

        void Updat_rue(KEY key, VALUE value)
        {
            typename stdext::hash_map<KEY,VALUE>::iterator itFind = records.find(key);
            if (itFind == records.end()) throw MyException::DBException("Key Not Found!");

            records.erase(key);
            records.insert( std::make_pair( key, value));
        }

        void Delet_rue(KEY key) { records.erase(key); }
    };

// 数据库基础字段类
struct ColNull{ };
template<class C1 = int, class C2 = ColNull, class C3 = ColNull, class C4 = ColNull, class C5 = ColNull
        ,class C6 = ColNull, class C7 = ColNull, class C8 = ColNull, class C9 = ColNull, class C10 = ColNull
        ,class C11 = ColNull, class C12 = ColNull, class C13 = ColNull, class C14 = ColNull, class C15 = ColNull
        ,class C16 = ColNull, class C17 = ColNull, class C18 = ColNull, class C19 = ColNull, class C20 = ColNull> 
    struct Columns 
   
        C1   col1; 
        C2   col2;
        C3   col3; 
        C4   col4;
        C5   col5; 
        C6   col6;
        C7   col7; 
        C8   col8;
        C9   col9; 
        C10  col10;
        C11  col11; 
        C12  col12;
        C13  col13; 
        C14  col14;
        C15  col15; 
        C16  col16;
        C17  col17; 
        C18  col18;
        C19  col19; 
        C20  col20;
    };

    namespace MySync // 同步对象(仅同步对象封装类是操作系统相关的)
    {
        #ifdef _WIN32

        // 同步对象封装类 - win32
        class ObjectSyncWin32
        {
            friend class ObjectSyncFactory;
            friend class PairGuard;
            CRITICAL_SECTION mtx;
            int refcount;
            std::string keyname;
        private:
            void Lock() { ::EnterCriticalSection(&mtx); ++refcount; }
            void Unlock() { --refcount; ::LeaveCriticalSection(&mtx); }
        public:
            ObjectSyncWin32(){ ::InitializeCriticalSection(&mtx); refcount = 0; }
            ObjectSyncWin32(std::string name){ keyname = name; ::InitializeCriticalSection(&mtx); refcount = 0; }
            ~ObjectSyncWin32(){ ::DeleteCriticalSection(&mtx); }
        };

        typedef ObjectSyncWin32 ObjectSync;

        #else // linux

        //同步对象封装类 - linux
        class ObjectSyncLinux
        {
            friend class ObjectSyncFactory;
            friend class PairGuard;
            pthread_mutex_t mtx;
            int refcount;
            std::string keyname;
        private:
            void Lock() { pthread_mutex_lock(&mtx); refcount = 0; }
            void Unlock() { --refcount; pthread_mutex_unlock(&mtx); }
        public:
            ObjectSyncLinux(){ pthread_mutex_init(&mtx, NULL); refcount = 0; }
            ObjectSyncLinux(std::string name){ keyname = name; pthread_mutex_init(&mtx, NULL); refcount = 0; }
            ~ObjectSyncLinux(){ pthread_mutex_destroy(&mtx); }
        };

        typedef ObjectSyncLinux ObjectSync;

        #endif

        // 同步对象工厂
        class ObjectSyncFactory
        {
            friend class PairGuard;
        private:
            ObjectSync m_globalLock;// 全局锁,用来锁定本对象,同步的获取其他锁
            stdext::hash_map<std::string, ObjectSync*> m_locks;//各个数据库表的行锁集合
        private://单件
            ObjectSyncFactory(){}
            ~ObjectSyncFactory(){}
            ObjectSyncFactory(const ObjectSyncFactory &) ;
            ObjectSyncFactory& operator=(const ObjectSyncFactory&) ;
        public:
            static ObjectSyncFactory* GetInstance() { static ObjectSyncFactory instance ; return &instance ; }
        private:
            void RemoveLock(ObjectSync* sem,std::string keyname)
            {
                m_globalLock.Lock();//全局锁定
           
                try
                {
                    stdext::hash_map<std::string, ObjectSync*>::iterator it = m_locks.find(keyname);
                    if(it != m_locks.end() && (*it).second == sem ) { delete sem; m_locks.erase(keyname); }
                }
                catch(...)
                {
                }

                m_globalLock.Unlock();//全局解锁
            }
        private:
            ObjectSync * GetLock(std::string keyname)
            {
                ObjectSync *pSync = NULL;

                m_globalLock.Lock();//全局锁定以获得行锁
               
                try
                {
                    stdext::hash_map<std::string, ObjectSync*>::iterator it = m_locks.find(keyname);

                    if(it == m_locks.end())
                    {
                        pSync = new ObjectSync(keyname);
                        m_locks.insert( std::make_pair(keyname, pSync));
                    }
                    else
                    {
                        pSync = (*it).second;
                    }
                }
                catch(...)
                {
                }

                m_globalLock.Unlock();//全局解锁

                return pSync;
            }
        public:
            template<class Type>
            ObjectSync * GetLock(std::string tablename, Type key)
            {
                std::stringstream ss;
                ss << tablename << "," << key;
                std::string keyname = ss.str();

                return GetLock(keyname);
            }
        };

        // 配对锁
        class PairGuard
        {
            ObjectSync* host;
            PairGuard(const PairGuard&);
            PairGuard& operator=(const PairGuard&);
        public:
            explicit PairGuard(ObjectSync* sem) : host(sem){ host->Lock(); }
            ~PairGuard(){ host->Unlock(); if(!host->refcount) ObjectSyncFactory::GetInstance()->RemoveLock(host,host->keyname); }
        };
    }

class db
{
private:
    stdext::hash_map<std::string, void*> m_tables;//各个数据库表集合
private://单件
    db(){}
    ~db(){}
    db(const db &) ;
    db& operator=(const db&) ;
public:
    static db& GetInstance() { static db instance ; return instance ; }
public:
    template<class Key, class Value>
    bool CreateTable(std::string tablename)//线程不安全函数(建议初始化时创建表,运行期间不得创建表)
    {
        typename stdext::hash_map<std::string, void*>::iterator it = m_tables.find(tablename);
        if(it != m_tables.end()) return false;

        Table<Key,Value>* tb = new Table<Key,Value>();

        m_tables.insert( std::make_pair(tablename, tb));
        return true;
    }

    template<class Key, class Value>
    bool DropTable(std::string tablename)//线程不安全函数(建议运行期间不得删除表)
    {
        typename stdext::hash_map<std::string, void*>::iterator it = m_tables.find(tablename);
        if(it != m_tables.end())
        {
            Table<Key,Value>* tb = (Table<Key,Value>*)((*it).second);
            if(tb)
            {
                delete tb;
                m_tables.erase(tablename);
                return true;
            }
        }

        return false;
    }

    template<class Key, class Value>
    bool AddValue(std::string tablename, Key key, Value value)
    {
        Table<Key,Value>* tb = NULL;
        typename stdext::hash_map<std::string, void*>::iterator it = m_tables.find(tablename);
        // 不存在该表
        if(it == m_tables.end()) return false;
       
        tb = (Table<Key,Value>*)((*it).second);
        if(!tb) return false;

        // 获得行锁
        MySync::PairGuard(MySync::ObjectSyncFactory::GetInstance()->GetLock(tablename,key));
        // 添加数据
        return tb->AddValue(key,value);
    }

    template<class Key, class Value>
    void Delet_rue(std::string tablename, Key key, Value value)
    {
        Table<Key,Value>* tb = NULL;
        typename stdext::hash_map<std::string, void*>::iterator it = m_tables.find(tablename);
        // 不存在该表
        if(it == m_tables.end()) return;
       
        tb = (Table<Key,Value>*)((*it).second);
        if(!tb) return;

        // 获得行锁
        MySync::PairGuard(MySync::ObjectSyncFactory::GetInstance()->GetLock(tablename,key));
        // 删除数据
        tb->Delet_rue(key,value);
    }

    template<class Key, class Value>
    void Updat_rue(std::string tablename, Key key, Value value)
    {
        Table<Key,Value>* tb = NULL;
        typename stdext::hash_map<std::string, void*>::iterator it = m_tables.find(tablename);
        // 不存在该表
        if(it == m_tables.end()) return;
       
        tb = (Table<Key,Value>*)((*it).second);
        if(!tb) return;

        // 获得行锁
        MySync::PairGuard(MySync::ObjectSyncFactory::GetInstance()->GetLock(tablename,key));
        // 更新数据
        tb->Updat_rue(key,value);
    }

    template<class Key, class Value>
    const Value&GetValue(std::string tablename, Key key)
    {
        Table<Key,Value>* tb = NULL;
        typename stdext::hash_map<std::string, void*>::iterator it = m_tables.find(tablename);
        // 不存在该表
        if(it == m_tables.end()) throw MyException::DBException("Table Not Found!");
       
        tb = (Table<Key,Value>*)((*it).second);
        if(!tb) throw MyException::DBException("Table Type Not dynamic_cast!");

        // 获得行锁
        MySync::PairGuard(MySync::ObjectSyncFactory::GetInstance()->GetLock(tablename,key));
        // 更新数据
        return tb->GetValue(key);
    }
};



}

以上是C++代码实现。


0

阅读 评论 收藏 转载 喜欢 打印举报/Report
  • 评论加载中,请稍候...
发评论

    发评论

    以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

      

    新浪BLOG意见反馈留言板 电话:4000520066 提示音后按1键(按当地市话标准计费) 欢迎批评指正

    新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 会员注册 | 产品答疑

    新浪公司 版权所有