public bool RemoveLine(NanoDBLine line, bool allowRecycle = true) { byte lineFlag = allowRecycle ? NanoDBConstants.LineFlagInactive : NanoDBConstants.LineFlagNoRecycle; lock (this.readLock) { if (!this.Accessible || !this.contentIndex.ContainsKey(line.Key) || this.shutdown) { return(false); } Interlocked.Increment(ref this.RunningTasks); this.contentIndex.Remove(line.Key); this.EmptyLines++; if (this.Sorted) { string sortKey = line.SortKey; if (this.sortIndex.ContainsKey(sortKey)) { this.sortIndex[sortKey].Remove(line); } } line.LineFlag = lineFlag; this.writer.AddTask(new NanoDBTask { Type = TaskType.RemoveLine, LineNumber = line.LineNumber, LineFlag = lineFlag }); } 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); }
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 LoadResult Load(int indexBy, int sortBy = -1) { if (!this.initialized) { return(LoadResult.NotIndexable); } if (indexBy < 0 || indexBy >= this.Layout.LayoutSize || !(this.Layout.Elements[indexBy] is StringElement)) { return(LoadResult.NotIndexable); } bool sort = sortBy >= 0 && sortBy < this.Layout.LayoutSize && sortBy != indexBy && this.Layout.Elements[sortBy] is StringElement; bool hasDuplicates = false; this.contentIndex = new Dictionary <string, NanoDBLine>(); this.sortIndex = sort ? new Dictionary <string, List <NanoDBLine> >() : null; using (FileStream stream = new FileStream(this.Path, FileMode.Open, FileAccess.Read)) { stream.Seek(this.Layout.HeaderSize, SeekOrigin.Begin); int lineFlag = stream.ReadByte(); while (lineFlag != -1) { if (lineFlag == NanoDBConstants.LineFlagActive) { object[] objects = new object[this.Layout.LayoutSize]; for (int i = 0; i < objects.Length; i++) { objects[i] = this.Layout.Elements[i].Parse(stream); } string key = (string)objects[indexBy]; string sortKey = sort ? (string)objects[sortBy] : null; if (this.contentIndex.ContainsKey(key)) { hasDuplicates = true; } else { NanoDBLine line = new NanoDBLine(this, NanoDBConstants.LineFlagActive, this.TotalLines, key, objects, sortKey); this.contentIndex[key] = line; if (sort) { if (this.sortIndex.ContainsKey(sortKey)) { this.sortIndex[sortKey].Add(line); } else { this.sortIndex[sortKey] = new List <NanoDBLine> { line }; } } } } else { stream.Seek(this.Layout.RowSize - 1, SeekOrigin.Current); this.EmptyLines++; } lineFlag = stream.ReadByte(); this.TotalLines++; } } this.indexedBy = indexBy; this.sortedBy = sortBy; this.Sorted = sort; return(hasDuplicates ? LoadResult.HasDuplicates : LoadResult.Okay); }