Example #1
0
        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);
        }
Example #2
0
        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);
        }
Example #3
0
        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);
        }
Example #4
0
        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);
        }
Example #5
0
        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);
        }