zoukankan      html  css  js  c++  java
  • 目前来说比较.net下最好的bdb操作封装(附单元测试)

      1using System;
      2using System.Collections.Generic;
      3using System.IO;
      4using System.Linq;
      5using System.Runtime.Serialization.Formatters.Binary;
      6using System.Text;
      7using BerkeleyDb;
      8using Component;
      9
     10namespace ToolManager
     11{
     12    public class BDBRecord
     13    {
     14        public object Key getset; }
     15        public string Value getset; }
     16    }
        /// <summary>
     17    /// BDB数据库操作类库
     18    /// </summary>

     19    public class BDBHelper
     20    {
     21
     22        private string DBFilePath getset; }
     23        private DBStoreType DBType getset; }
     24        public enum DBStoreType : byte
     25        {
     26            Auto=1,
     27            Queue,
     28            Hash
     29        }

     30        [Obsolete("该构造函数已废弃 ,请使用BDBHelper(string dbfilePath)")]
     31        public BDBHelper()
     32        {
     33        }

     34
     35        public BDBHelper(string dbfilePath)
     36        {
     37            this.DBFilePath = dbfilePath;
     38        }

     39        [Obsolete("该构造函数已废弃 ,请使用BDBHelper(string dbfilePath)")]
     40        public BDBHelper(string dbfilePath, DBStoreType type)
     41        {
     42            this.DBFilePath = dbfilePath;
     43            this.DBType = type;
     44        }

     45        public BDBRecord FindOne()
     46        {
     47            return this.FindOne(null);
     48        }

     49        public BDBRecord FindOne(Func<objectstringbool> predicate)
     50        {
     51            //Dictionary<string, object> dict = new Dictionary<string, object>();
     52            try
     53            {
     54                Queue格式
     85            }

     86            catch (Exception ex)
     87            {
     88                Hash格式
    121                //}
    122            }

    123            //return dict;
    124            return null;
    125        }

    126        public Dictionary<objectstring> FindAll(Func<objectstringbool> predicate)
    127        {
    128
    129            Dictionary<objectstring> dict = new Dictionary<objectstring>();
    130            try
    131            {
    132                Queue格式
    150            }

    151            catch (Exception ex)
    152            {
    153                Hash格式
    173                //}
    174            }

    175            return dict;
    176        }

    177        public Dictionary<objectstring> FindAll()
    178        {
    179            //either below works fine
    180            //return this.FindAll((s, o) => true);
    181            return this.FindAll(null);
    182        }

    183        private static void _Do(KeyDataPair kvp, Func<objectstringbool> predicate, Dictionary<objectstring> result)
    184        {
    185            BinaryFormatter bf = new BinaryFormatter();
    186            MemoryStream stream = new MemoryStream();
    187            stream.Write(kvp.Data.Buffer, 0, kvp.Data.Size);
    188            stream.Seek(0, SeekOrigin.Begin);
    189            string k = Encoding.UTF8.GetString(kvp.Key.Buffer, 0, kvp.Key.Size);
    190            object v = bf.Deserialize(stream);
    191            if (predicate == null)
    192            {
    193                result.Add(v, k);
    194            }

    195            else if (predicate(v, k))
    196            {
    197                result.Add(v, k);
    198            }

    199        }

    200        private static void _Do2(KeyDataPair kvp, Func<objectstringbool> predicate, Dictionary<objectstring> result)
    201        {
    202            BinaryFormatter bf = new BinaryFormatter();
    203            MemoryStream stream = new MemoryStream();
    204            stream.Write(kvp.Data.Buffer, 0, kvp.Data.Size);
    205            stream.Seek(0, SeekOrigin.Begin);
    206            string k = BitConverter.ToInt32(kvp.Key.Buffer, 0).ToString();
    207            object v = bf.Deserialize(stream);
    208            if (predicate == null)
    209            {
    210                result.Add(v, k);
    211            }

    212            else if (predicate(v, k))
    213            {
    214                result.Add(v, k);
    215            }

    216        }

    217        /// <summary>
    218        /// 更新数据库中的数据
    219        /// </summary>
    220        /// <param name="predicate">execute condition</param>
    221        /// <param name="isMatchOnlyOnce">is match only once</param>
    222        /// <returns>effect records</returns>

    223        public int UpdateInQueueMode(Func<intobjectbool> predicate, object value,bool isMatchOnlyOnce)
    224        {
    225                 int count = 0;
    226                 if (predicate == null)
    227                     return 0;
    228               //遍历数据
    229                using (Db db = new Db(DbCreateFlags.None))
    230                {
    231                    db.RecLen = 5000;
    232                    db.RecPad = '.';
    233                    //这里如果应用Db.OpenFlags.Create则在启动后会覆盖同名文件,并新建同名文件
    234                    //Db.OpenFlags.Truncate会清空数据库
    235                    DbQueue dbf = (DbQueue)db.Open(nullthis.DBFilePath, null, DbType.Queue,
    236        Db.OpenFlags.ThreadSafe|Db.OpenFlags.Create, 0);
    237
    238                    using (DbQueueCursor cursor = dbf.OpenCursor(null, DbFileCursor.CreateFlags.None))
    239                    {
    240                        BinaryFormatter bf = new BinaryFormatter();
    241                        MemoryStream stream = new MemoryStream();
    242                        foreach (KeyDataPair kdp in cursor)
    243                        {
    244                            int k = BitConverter.ToInt32(kdp.Key.Buffer, 0);
    245                            Console.WriteLine("k={0}", k.ToString());
    246                            stream.SetLength(0);
    247                            stream.Position = 0;
    248                            stream.Write(kdp.Data.Buffer, 0, kdp.Data.Size);
    249                            stream.Seek(0, SeekOrigin.Begin);
    250                            object v = bf.Deserialize(stream);
    251                            if(predicate(k,v))
    252                            {
    253                                count++;
    254                                //string d = Encoding.UTF8.GetString(kdp.Data.Buffer, 0, kdp.Data.Size);
    255                                //如何读取Queue类型的主键值
    256
    257
    258                                //Console.WriteLine("{0},{1}", p2.State, p2.Os);
    259                                //p2.Os = "changed";
    260                                //stream = new MemoryStream();
    261                                stream.Position = 0;
    262                                stream.SetLength(0);
    263                                bf.Serialize(stream, value);
    264                                DbEntry data = DbEntry.InOut(stream.ToArray());
    265                                cursor.Put(ref data);
    266                                if (isMatchOnlyOnce)
    267                                {
    268                                    stream.Close();
    269                                    return count;
    270                                }

    271                            }

    272                        }

    273                            stream.Close();
    274                    }

    275            }

    276            return count;
    277        }

    278
    279        public void CreateInQueueMode(object value)
    280        {
    281            Db PC = new Db(DbCreateFlags.None);
    282            PC.RecLen = 5000;
    283            PC.RecPad = '.';
    284            DbQueue file = (DbQueue)PC.Open(nullthis.DBFilePath, null, DbType.Queue, Db.OpenFlags.Create|Db.OpenFlags.ThreadSafe, 0);
    285            //CreateSecondaryDB(file,"Id.PCs.s",new DbFile.KeyGeneratorFcn(Common.Id));
    286            //CreateSecondaryDB(file, "Id.PCs.s", new DbFile.KeyGeneratorFcn(Common.Id));
    287            //由于数据量不是很大,不考虑使用二级数据库,直接使用游标操作,降低复杂度
    288            //首先遍历数据库看有没有已经存在,如果没有,则添加一个,如果有,改变其状态
    289            BinaryFormatter bf = new BinaryFormatter();
    290            MemoryStream stream= new MemoryStream();
    291            bf.Serialize(stream, value);
    292            DbEntry k = DbEntry.Out(new byte[1024]);
    293            DbEntry data = DbEntry.InOut(stream.ToArray());
    294            file.Append(nullref k, ref data);
    295            stream.Close();
    296            file.Sync();
    297            PC.Close();
    298        }

    299        public int DeleteInQueueMode(Func<intobjectbool> predicate,bool isMatchOnlyOnce)
    300        {
    301            int count = 0;
    302            if (predicate == null)
    303                return 0;
    304            //遍历数据
    305            using (Db db = new Db(DbCreateFlags.None))
    306            {
    307                db.RecLen = 5000;
    308                db.RecPad = '.';
    309                //这里如果应用Db.OpenFlags.Create则在启动后会覆盖同名文件,并新建同名文件
    310                //Db.OpenFlags.Truncate会清空数据库
    311                DbQueue dbf = (DbQueue)db.Open(nullthis.DBFilePath, null, DbType.Queue,
    312    Db.OpenFlags.ThreadSafe|Db.OpenFlags.Create, 0);
    313
    314                using (DbQueueCursor cursor = dbf.OpenCursor(null, DbFileCursor.CreateFlags.None))
    315                {
    316                    BinaryFormatter bf = new BinaryFormatter();
    317                    MemoryStream stream = new MemoryStream();
    318                    foreach (KeyDataPair kdp in cursor)
    319                    {
    320                        int k = BitConverter.ToInt32(kdp.Key.Buffer, 0);
    321                        Console.WriteLine("k={0}", k.ToString());
    322                        stream.SetLength(0);
    323                        stream.Position = 0;
    324                        stream.Write(kdp.Data.Buffer, 0, kdp.Data.Size);
    325                        stream.Seek(0, SeekOrigin.Begin);
    326                        object v = bf.Deserialize(stream);
    327                        if (predicate(k, v))
    328                        {
    329                            count++;
    330                            //string d = Encoding.UTF8.GetString(kdp.Data.Buffer, 0, kdp.Data.Size);
    331                            //如何读取Queue类型的主键值
    332
    333
    334                            //Console.WriteLine("{0},{1}", p2.State, p2.Os);
    335                            //p2.Os = "changed";
    336                            //stream = new MemoryStream();
    337                            //stream.Position = 0;
    338                            //stream.SetLength(0);
    339                            //bf.Serialize(stream, v);
    340                            //DbEntry data = DbEntry.InOut(stream.ToArray());
    341                            //cursor.Put(ref data);
    342                            cursor.Delete();
    343                            if (isMatchOnlyOnce)
    344                            {
    345                                stream.Close();
    346                                return count;
    347                            }

    348                        }

    349                    }
    stream.Close();
    350                }

    351            }

    352            return count;
    353        }

    354
    355        /// <summary>
    356        /// 用于向支持重复键值的数据库文件添加数据
    357        /// </summary>
    358        /// <param name="key"></param>
    359        /// <param name="value"></param>

    360        public void CreateInHashModeWithDup(string key,object value)
    361        {
    362            //这里只是更新了一条记录,更新多条同key的情况没有考虑
    363            Db db = new Db(DbCreateFlags.None);
    364            db.SetFlags(DbFlags.Dup);
    365            DbFile dbf = db.Open(nullthis.DBFilePath, null, DbType.Hash, Db.OpenFlags.Create|Db.OpenFlags.ThreadSafe, 0);
    366            MemoryStream stream = new MemoryStream();
    367            BinaryFormatter formatter = new BinaryFormatter();
    368            formatter.Serialize(stream, value);
    369            DbEntry _key = DbEntry.InOut(Encoding.UTF8.GetBytes(key));
    370            DbEntry _data = DbEntry.InOut(stream.ToArray());
    371            if (dbf.Put(nullref _key, ref _data) != 0)
    372                Console.Write("{0}:输入错误", key);
    373            stream.Close();
    374            dbf.Sync();//数据更新 
    375            db.Close();
    376        }

    377        /// <summary>
    378        /// 默认方式,如果已有键则进行更新操作
    379        /// </summary>
    380        /// <param name="key"></param>
    381        /// <param name="value"></param>

    382        public void CreateOrUpdateInHashModeWithoutDup(string key,object value)
    383        {
    384            //这里只是更新了一条记录,更新多条同key的情况没有考虑
    385            Db db = new Db(DbCreateFlags.None);
    386            //db.SetFlags(DbFlags.Dup);
    387            DbFile dbf = db.Open(nullthis.DBFilePath, null, DbType.Hash, Db.OpenFlags.Create|Db.OpenFlags.ThreadSafe, 0);
    388            MemoryStream stream = new MemoryStream();
    389            BinaryFormatter formatter = new BinaryFormatter();
    390            formatter.Serialize(stream, value);
    391            DbEntry _key = DbEntry.InOut(Encoding.UTF8.GetBytes(key));
    392            DbEntry _data = DbEntry.InOut(stream.ToArray());
    393            if (dbf.Put(nullref _key, ref _data) != 0)
    394                Console.Write("{0}:输入错误", key);
    395            stream.Close();
    396            dbf.Sync();//数据更新 
    397            db.Close();
    398        }

    399        public int UpdateInHashMode(Func<string,object,bool> predicate,object value,bool isMatchOnlyOnce)
    400        {
    401            int count = 0;
    402            if (predicate == null)
    403                return count;
    404           //遍历数据
    405            using (Db db = new Db(DbCreateFlags.None))
    406            {
    407                //这里如果应用Db.OpenFlags.Create则在启动后会覆盖同名文件,并新建同名文件
    408                //Db.OpenFlags.Truncate会清空数据库
    409                DbHash dbf = (DbHash)db.Open(nullthis.DBFilePath, null, DbType.Hash,
    410    Db.OpenFlags.ThreadSafe|Db.OpenFlags.Create, 0);
    411
    412                using (DbHashCursor cursor = dbf.OpenCursor(null, DbFileCursor.CreateFlags.None))
    413                {
    414                    BinaryFormatter bf = new BinaryFormatter();
    415                    MemoryStream stream = new MemoryStream();
    416                   foreach (KeyDataPair kvp in cursor)
    417                    {
    418                        stream.SetLength(0);
    419                        stream.Position = 0
    420                        stream.Write(kvp.Data.Buffer, 0, kvp.Data.Size);
    421                        stream.Seek(0, SeekOrigin.Begin);
    422                        string k = Encoding.UTF8.GetString(kvp.Key.Buffer, 0, kvp.Key.Size);
    423                        object v = bf.Deserialize(stream);
    424                        if (predicate(k, v))
    425                        {
    426                            count++;
    427                            stream.SetLength(0);
    428                            stream.Position = 0;
    429                            bf.Serialize(stream, value);
    430                            DbEntry data = DbEntry.InOut(stream.ToArray());
    431                            cursor.Put(ref data, DbKeyCursor<DbHashCursor, DbHash>.PutMode.Current);
    432                            if (isMatchOnlyOnce)
    433                            {
    434                                stream.Close();
    435                                return count;
    436                            }

    437                        }

    438                    }

    439                    stream.Close();
    440                }

    441            }

    442            return count;
    443        }

    444        public int DeleteInHashMode(Func<string,object,bool> predicate,bool isMatchOnlyOnce)
    445        {
    446            int count = 0;
    447            if (predicate == null)
    448                return count;
    449            //遍历数据
    450            using (Db db = new Db(DbCreateFlags.None))
    451            {
    452                //这里如果应用Db.OpenFlags.Create则在启动后会覆盖同名文件,并新建同名文件
    453                //Db.OpenFlags.Truncate会清空数据库
    454                DbHash dbf = (DbHash)db.Open(nullthis.DBFilePath, null, DbType.Hash,
    455    Db.OpenFlags.ThreadSafe|Db.OpenFlags.Create, 0);
    456
    457                using (DbHashCursor cursor = dbf.OpenCursor(null, DbFileCursor.CreateFlags.None))
    458                {
    459                    BinaryFormatter bf = new BinaryFormatter();
    460                    MemoryStream stream = new MemoryStream();
    461                    foreach (KeyDataPair kvp in cursor)
    462                    {
    463                        stream.SetLength(0);
    464                        stream.Position = 0;
    465                        stream.Write(kvp.Data.Buffer, 0, kvp.Data.Size);
    466                        stream.Seek(0, SeekOrigin.Begin);
    467                        string k = Encoding.UTF8.GetString(kvp.Key.Buffer, 0, kvp.Key.Size);
    468                        object v = bf.Deserialize(stream);
    469                        if (predicate(k, v))
    470                        {
    471                            count++;
    472                            cursor.Delete();
    473                            if (isMatchOnlyOnce)
    474                            {
    475                                stream.Close();
    476                                return count;
    477                            }

    478                        }

    479                    }

    480                    stream.Close();
    481                }

    482            }

    483            return count;
    484        }

    485    }

    486}

    487

    unit test code

      1using System;
      2using System.Collections.Generic;
      3using System.Linq;
      4using System.Text;
      5using Component;
      6using MbUnit.Framework;
      7
      8namespace ToolManager.Test
      9{
     10    [TestFixture]
     11    class BDBHelperTest2
     12    {
     13        hash mode unit test
     69
     70        queue mode unit test
    103
    104    }

    105}

    106
  • 相关阅读:
    C# struct 性能损失
    [leetcode] Scramble String @python
    [leetcode]Symmetric Tree @ Python
    [leetcode] Maximum Product Subarray @ python
    [leetcode]Surrounded Regions @ Python
    [leetcode]N-Queens @ Python
    [leetcode] Combinations @ Python [ask for help]
    [leetcode]Next Permutation @ Python
    [building block] merge sort @ Python
    [leetcode] Integer to Roman @ Python
  • 原文地址:https://www.cnblogs.com/lexus/p/1275164.html
Copyright © 2011-2022 走看看