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