【散300分】由 EXtremeDB 想到的扯淡“技术”——示例如何自己编写内存数据库.
我曾经写过一点短文来介绍如何编写ORM接口以及实现接口,甚至还包括触发器等。今天正好看到了介绍 EXtremeDB 等的文章,于是想到给我们死水一潭的 csdn 提供一份扯淡文章,借助我以前介绍的 ORM 接口来让我们的 .net 程序员感受一下如何开始实现一个不一样的DAL。
好了,先写出 DAL 的接口规范:
using System;using System.Linq;namespace MyName{ public interface IDomain : IDisposable { IQueryable<T> Cast<T>() where T : class; void Activate<T>(T obj); void Save<T>(T obj); void Delete<T>(T obj); void Commit(); void Rollback(); }}public class XiaoHuiDomain : IDomain{ private static Dictionary<int, object> _datas = new Dictionary<int, object>(); public IQueryable<T> Cast<T>() where T : class { return _datas.Values.OfType<T>().AsQueryable(); } public void Activate<T>(T obj) { } private Dictionary<int, object> Locked = new Dictionary<int, object>(); public void Save<T>(T obj) { if (!Monitor.TryEnter(obj, 20000)) throw new TimeoutException(); var key = obj.GetHashCode(); if (!Locked.ContainsKey(key)) Locked.Add(key, obj); if (!_datas.ContainsKey(key)) _datas.Add(key, obj); } public void Delete<T>(T obj) { _datas.Remove(obj.GetHashCode()); } public void Commit() { } public void Rollback() { throw new NotImplementedException(); } public void Dispose() { foreach (var x in Locked) Monitor.Exit(x.Value); }}class Program{ static void Main(string[] args) { var datas = new List<UU>(); var n = 50; var value = Encoding.Default.GetBytes("1234567890123456"); Debug.Assert(value.Length == 16); { var tm = new Stopwatch(); tm.Start(); for (var x = 0; x < n; x++) { for (var y = 0; y < 10000; y++) datas.Add(new UU { dt = value }); } tm.Stop(); Console.WriteLine("内存{0}个对象共用时{1},平均{2}条记录/秒,{3}微妙/条。", n * 10000, tm.Elapsed, (int)((n * 10000) / tm.Elapsed.TotalSeconds), tm.ElapsedMilliseconds / 10 / n); } using (var dd = new XiaoHuiDomain()) { var tm = new Stopwatch(); tm.Start(); for (var x = 0; x < n; x++) { for (var y = 0; y < 10000; y++) dd.Save(new UU { dt = value }); } dd.Commit(); tm.Stop(); Console.WriteLine("写入{0}个对象共用时{1},平均{2}条记录/秒,{3}微妙/条。", n * 10000, tm.Elapsed, (int)((n * 10000) / tm.Elapsed.TotalSeconds), tm.ElapsedMilliseconds / 10 / n); } using (var dd = new SqlDomain()) { var tm = new Stopwatch(); tm.Start(); for (var x = 0; x < n; x++) { for (var y = 0; y < 10000; y++) dd.Save(new UU { dt = value }); } dd.Commit(); tm.Stop(); Console.WriteLine("写入{0}个对象共用时{1},平均{2}条记录/秒,{3}微妙/条。", n * 10000, tm.Elapsed, (int)((n * 10000) / tm.Elapsed.TotalSeconds), tm.ElapsedMilliseconds / 10 / n); } using (var dd = new MySQLDomain()) { var cn = dd.Cast<UU>().Count(); UU x; var tm = new Stopwatch(); tm.Start(); dd.Cast<UU>().ForEach(u => { x = u; }); tm.Stop(); Console.WriteLine("读取{0}个对象共用时{1},平均{2}条记录/秒,{3}微妙/条。", n, tm.Elapsed, (int)(cn / tm.Elapsed.TotalSeconds), tm.ElapsedMilliseconds * 1000 / cn); } Console.ReadKey(); }}class UU{ public byte[] dt { get; set; }}