public InitializeResult Initialize() { using (FileStream stream = new FileStream(this.Path, FileMode.OpenOrCreate, FileAccess.Read)) { byte[] magicBytes = new byte[NanoDBConstants.MagicBytes.Length]; if (stream.Read(magicBytes, 0, NanoDBConstants.MagicBytes.Length) != NanoDBConstants.MagicBytes.Length) { return(InitializeResult.FileEmpty); } int version = stream.ReadByte(); if (version != NanoDBConstants.DatabaseStructureVersion) { return(version > 0 ? InitializeResult.VersionMismatch : InitializeResult.FileEmpty); } int layoutSize = stream.ReadByte(); if (layoutSize <= 0) { return(InitializeResult.FileCorrupt); } int recommendedIndex = stream.ReadByte(); if (recommendedIndex < 0 || recommendedIndex >= layoutSize) { return(InitializeResult.FileCorrupt); } this.RecommendedIndex = recommendedIndex; byte[] layoutIds = new byte[layoutSize]; if (stream.Read(layoutIds, 0, layoutSize) < layoutSize) { return(InitializeResult.FileCorrupt); } NanoDBElement[] elements = new NanoDBElement[layoutSize]; for (int i = 0; i < layoutSize; i++) { NanoDBElement element = NanoDBElement.Elements[layoutIds[i]]; if (element == null) { return(InitializeResult.UnknownDataType); } elements[i] = element; } this.Layout = new NanoDBLayout(elements); if ((stream.Length - this.Layout.HeaderSize) % this.Layout.RowSize != 0) { return(InitializeResult.UnexpectedFileEnd); } this.initialized = true; return(InitializeResult.Success); } }
public bool UpdateLine(NanoDBLine line, params object[] objects) { lock (this.readLock) { if (!this.Accessible || !this.contentIndex.ContainsKey(line.Key) || objects.Length != this.Layout.LayoutSize || this.shutdown) { return(false); } Interlocked.Increment(ref this.RunningTasks); int position = 1; byte[] data = new byte[this.Layout.RowSize]; data[0] = NanoDBConstants.LineFlagCorrupt; for (int i = 0; i < objects.Length; i++) { NanoDBElement element = this.Layout.Elements[i]; if (element.IsValidElement(objects[i])) { if (i == this.indexedBy) { string newKey = (string)objects[i]; if (newKey != line.Key && this.contentIndex.ContainsKey(newKey)) { Interlocked.Decrement(ref this.RunningTasks); return(false); } this.contentIndex.Remove(line.Key); this.contentIndex[newKey] = line; line.Key = newKey; } else if (this.Sorted && i == this.sortedBy) { string newSortKey = (string)objects[i]; if (this.sortIndex.ContainsKey(newSortKey)) { this.sortIndex[newSortKey].Add(line); } else { this.sortIndex[newSortKey] = new List <NanoDBLine> { line }; } this.sortIndex[line.SortKey].Remove(line); line.SortKey = newSortKey; } element.Write(objects[i], data, position); position += element.Size; line.Content[i] = objects[i]; } } this.writer.AddTask(new NanoDBTask { Type = TaskType.UpdateLine, LineNumber = line.LineNumber, Data = data }); } return(true); }
public bool UpdateObject(NanoDBLine line, int layoutIndex, object obj) { lock (this.readLock) { if (!this.Accessible || !this.contentIndex.ContainsKey(line.Key) || layoutIndex < 0 || layoutIndex >= this.Layout.LayoutSize || this.shutdown) { return(false); } Interlocked.Increment(ref this.RunningTasks); NanoDBElement element = this.Layout.Elements[layoutIndex]; if (!element.IsValidElement(obj)) { Interlocked.Decrement(ref this.RunningTasks); return(false); } if (layoutIndex == this.indexedBy) { string newKey = (string)obj; if (this.contentIndex.ContainsKey(newKey)) { Interlocked.Decrement(ref this.RunningTasks); return(false); } this.contentIndex[newKey] = line; this.contentIndex.Remove(line.Key); line.Key = newKey; } else if (this.Sorted && layoutIndex == this.sortedBy) { string newSortKey = (string)obj; if (this.sortIndex.ContainsKey(newSortKey)) { this.sortIndex[newSortKey].Add(line); } else { this.sortIndex[newSortKey] = new List <NanoDBLine> { line }; } this.sortIndex[line.SortKey].Remove(line); line.SortKey = newSortKey; } line.Content[layoutIndex] = obj; byte[] data = new byte[element.Size]; element.Write(obj, data, 0); this.writer.AddTask(new NanoDBTask { Type = TaskType.UpdateObject, LineNumber = line.LineNumber, Data = data, LayoutIndex = layoutIndex }); } return(true); }
public NanoDBLine AddLine(params object[] objects) { string key; lock (this.readLock) { if (!this.Accessible || objects.Length != this.Layout.LayoutSize || this.shutdown) { return(null); } Interlocked.Increment(ref this.RunningTasks); key = (string)objects[this.indexedBy]; if (key == null || this.contentIndex.ContainsKey(key)) { Interlocked.Decrement(ref this.RunningTasks); return(null); } } int position = 1; byte[] data = new byte[this.Layout.RowSize]; data[0] = NanoDBConstants.LineFlagIncomplete; for (int i = 0; i < objects.Length; i++) { NanoDBElement element = this.Layout.Elements[i]; if (element.IsValidElement(objects[i])) { element.Write(objects[i], data, position); position += element.Size; } else { Interlocked.Decrement(ref this.RunningTasks); return(null); } } NanoDBLine line = new NanoDBLine(this, NanoDBConstants.LineFlagActive, this.TotalLines, key, objects); lock (this.readLock) { if (!this.Accessible || this.contentIndex.ContainsKey(key)) { Interlocked.Decrement(ref this.RunningTasks); return(null); } this.TotalLines++; this.contentIndex[key] = line; if (this.Sorted) { string sortKey = (string)objects[this.sortedBy]; if (this.sortIndex.ContainsKey(sortKey)) { this.sortIndex[sortKey].Add(line); } else { this.sortIndex[sortKey] = new List <NanoDBLine> { line }; } } this.writer.AddTask(new NanoDBTask { Type = TaskType.AddLine, Data = data }); } return(line); }