private void InitFirstBlock(DBCreateOption createOption) { //数据库需要初始化 if (createOption == null) { this.Close(); throw new Exception("数据库需要初始化 open(path,createOption)"); } else { var writetask = new WriteTask(); writetask.CreateTable(new TableInfo(systemtable_info, "_table_info", null, DBValue.Type.String)); writetask.CreateTable(new TableInfo(systemtable_block, "_table_block", null, DBValue.Type.UINT64)); if (createOption.FirstTask != null) { foreach (var t in createOption.FirstTask.items) { writetask.items.Add(t); } } writetask.Put(systemtable_info, "_magic_".ToBytes_UTF8Encode(), DBValue.FromValue(DBValue.Type.String, createOption.MagicStr)); this.WriteUnsafe(writetask, createOption.afterparser); } }
public static WriteTask UnPack(System.IO.Stream stream) { var task = new WriteTask(); var extcount = stream.ReadByte(); if (extcount > 0) { task.extData = new Dictionary <string, byte[]>(); } for (var i = 0; i < extcount; i++) { var numkey = stream.ReadByte(); byte[] bufnum = new byte[4]; var numv = stream.Read(bufnum, 0, 4); UInt32 numValue = BitConverter.ToUInt32(bufnum, 0); byte[] bufv = new byte[Math.Max(numkey, numValue)]; stream.Read(bufv, 0, numkey); var strkey = System.Text.Encoding.UTF8.GetString(bufv, 0, numkey); stream.Read(bufv, 0, (int)numValue); task.extData[strkey] = bufv; } byte[] bufnumitem = new byte[2]; stream.Read(bufnumitem, 0, 2); var numitem = BitConverter.ToUInt16(bufnumitem, 0); for (var i = 0; i < numitem; i++) { task.items.Add(WriteTaskItem.UnPack(stream)); } return(task); }
public void Write(WriteTask task, Action <WriteTask, byte[], IWriteBatch> afterparser = null) { foreach (var item in task.items) { //if (item.tableID != null && item.tableID.Length < 2) // throw new Exception("table id is too short."); } WriteUnsafe(task, afterparser); }
//写入操作需要保持线性,线程安全 private void WriteUnsafe(WriteTask task) { lock (systemtable_block) { using (var wb = new WriteBatch(this.db.Handle, snapshotLast)) { var heightbuf = BitConverter.GetBytes(snapshotLast.DataHeight); foreach (var item in task.items) { if (item.value != null) { DBValue.QuickFixHeight(item.value, heightbuf); } switch (item.op) { case WriteTaskOP.CreateTable: wb.CreateTable(item.tableID, item.value); break; case WriteTaskOP.DeleteTable: wb.DeleteTable(item.tableID); break; case WriteTaskOP.PutValue: wb.PutUnsafe(item.tableID, item.key, item.value); break; case WriteTaskOP.DeleteValue: wb.Delete(item.tableID, item.key); break; case WriteTaskOP.Log: break; } } var taskblock = task.ToBytes(); //还要把这个block本身写入,高度写入 var finaldata = DBValue.FromValue(DBValue.Type.Bytes, taskblock).ToBytes(); DBValue.QuickFixHeight(finaldata, heightbuf); var blockkey = BitConverter.GetBytes(snapshotLast.DataHeight); wb.PutUnsafe(systemtable_block, blockkey, finaldata); //wb.Put(systemtable_block, height, taskblock); //height++ var finalheight = DBValue.FromValue(DBValue.Type.UINT64, (ulong)(snapshotLast.DataHeight + 1)).ToBytes(); DBValue.QuickFixHeight(finalheight, heightbuf); wb.PutUnsafe(systemtable_info, "_height".ToBytes_UTF8Encode(), finalheight); RocksDbSharp.Native.Instance.rocksdb_write(this.db.Handle, this.defaultWriteOpPtr, wb.batchptr); //this.db.Write(wb.batch); snapshotLast.Dispose(); snapshotLast = CreateSnapInfo(); snapshotLast.AddRef(); } } }
public void Write(WriteTask task) { foreach (var item in task.items) { if (item.tableID != null && item.tableID.Length < 2) { throw new Exception("table id is too short."); } } WriteUnsafe(task); }
private void InitFirstBlock(DBCreateOption createOption) { //数据库需要初始化 if (createOption == null) { this.Close(); throw new Exception("数据库需要初始化 open(path,createOption)"); } else { var writetask = new WriteTask(); writetask.CreateTable(new TableInfo(systemtable_info, "_table_info", null, DBValue.Type.String)); writetask.CreateTable(new TableInfo(systemtable_block, "_table_block", null, DBValue.Type.UINT64)); if (createOption.FirstTask != null) { foreach (var t in createOption.FirstTask.items) { writetask.items.Add(t); } } this.WriteUnsafe(writetask); } }
//写入操作需要保持线性,线程安全 //writetask 会被修改 //所以要返回一个bytearray 留给外部 private void WriteUnsafe(WriteTask task, Action <WriteTask, byte[], IWriteBatch> afterparser) { lock (systemtable_block) { using (var wb = new WriteBatch(this.dbPtr, snapshotLast)) { //先写入原始block //先抽数据,之后就会改变了 var taskblock = task.ToBytes(); //还要把这个block本身写入,高度写入 var finaldata = DBValue.FromValue(DBValue.Type.Bytes, taskblock); wb.Put(systemtable_block, snapshotLast.DataHeightBuf, finaldata); //逐个执行每一个writetask //var heightbuf = BitConverter.GetBytes(snapshotLast.DataHeight); foreach (var item in task.items) { if (item.value != null) { item.value = DBValue.QuickFixHeight(item.value, snapshotLast.DataHeightBuf); } switch (item.op) { case WriteTaskOP.CreateTable: wb.CreateTable(item.tableID, item.value); break; case WriteTaskOP.DeleteTable: wb.DeleteTable(item.tableID); break; case WriteTaskOP.PutValue: wb.PutUnsafe(item.tableID, item.key, item.value); break; case WriteTaskOP.DeleteValue: wb.Delete(item.tableID, item.key); break; case WriteTaskOP.Log: break; } } //在高度增加之前给一个回调插入处理的时机 if (afterparser != null) { afterparser(task, taskblock, wb); } //增加高度 //height++ var finalheight = DBValue.FromValue(DBValue.Type.UINT64, (ulong)(snapshotLast.DataHeight + 1)); wb.Put(systemtable_info, "_height".ToBytes_UTF8Encode(), finalheight); RocksDbSharp.Native.Instance.rocksdb_write(this.dbPtr, this.defaultWriteOpPtr, wb.batchptr); //this.db.Write(wb.batch); snapshotLast.Dispose(); snapshotLast = CreateSnapInfo(); snapshotLast.AddRef(); //return finaldata; } } }
private void AddHeight(WriteTask task) { }