public long Add(T value, long data, IComparer <T> _comparer) { var _value = _dataStorage.ReadObject(_data); var result = _comparer.Compare(value, _value); if (result < 0) { if (_left > 0) { var node = GetNode(_left); return(node.Add(value, data, _comparer)); } else { var node = new Node <T>(value, data, this, _indexStorage, _dataStorage, _duplicable); _left = node._offset; Save(); return(node._data); } } else if (result > 0) { if (_right > 0) { var node = GetNode(_right); return(node.Add(value, data, _comparer)); } else { var node = new Node <T>(value, data, this, _indexStorage, _dataStorage, _duplicable); _right = node._offset; Save(); return(node._data); } } else if (!_duplicable) { throw new InvalidDataException(); } data = data > 0 ? data : _dataStorage.WriteObject(value); _duplicates.Add(data); Save(); return(data); }
public Node(long offset, Node <T> parent, ObjectStorage <IndexNode> indexStorage, ObjectStorage <T> dataStorage, bool duplicable) { _parent = parent; _indexStorage = indexStorage; _dataStorage = dataStorage; var indexNode = indexStorage.ReadObject(offset); _duplicable = duplicable; _duplicates = duplicable ? new List <long>() : null; foreach (var dataOffset in indexNode.Duplicates) { _duplicates.Add(dataOffset); } _offset = offset; _data = indexNode.Data; _left = indexNode.Left; _right = indexNode.Right; }
public void ObjectStorageTest() { var currentDirectory = Directory.GetCurrentDirectory(); var personDbFilePath = Path.Combine(currentDirectory, "test.person.db"); var storage = new ObjectStorage <Person>(personDbFilePath, FileMode.Create); storage.ObjectHeaderSize.Should().Be(32); storage.ObjectInfoSize.Should().Be(24); var p1 = new Person { Id = 1, Name = "First", Age = 20 }; var p2 = new Person { Id = 2, Name = "Second", Age = 25 }; var p3 = new Person { Id = 3, Name = "Third", Age = 30 }; var p4 = new Person { Id = 4, Name = "Forth", Age = 20 }; var p5 = new Person { Id = 5, Name = "Fifth", Age = 15 }; var p6 = new Person { Id = 6, Name = "Large object will append to the file", Age = 40 }; var p2new = new Person { Id = 2, Name = "2nd", Age = 25 }; var p3new = new Person { Id = 3, Name = "3th", Age = 30 }; var p4new = new Person { Id = 4, Name = "4th", Age = 20 }; var p2newest = new Person { Id = 2, Name = "2nd", Age = 32 }; var o1 = storage.WriteObject(p1); var o2 = storage.WriteObject(p2); var o3 = storage.WriteObject(p3); var o4 = storage.WriteObject(p4); var o5 = storage.WriteObject(p5); o1.Should().Be(32); o2.Should().Be(94); o3.Should().Be(157); o4.Should().Be(219); o5.Should().Be(281); ValidatePerson(storage.ReadObject(o1), p1); ValidatePerson(storage.ReadObject(o2), p2); ValidatePerson(storage.ReadObject(o3), p3); ValidatePerson(storage.ReadObject(o4), p4); ValidatePerson(storage.ReadObject(o5), p5); storage.DeleteObject(o4); storage.DeleteObject(o2); storage.DeleteObject(o3); // Can not read the deleted offset Action readO2 = () => { storage.ReadObject(o2); }; readO2.Should().Throw <Exception>(); Action readO3 = () => { storage.ReadObject(o3); }; readO3.Should().Throw <Exception>(); Action readO4 = () => { storage.ReadObject(o4); }; readO4.Should().Throw <Exception>(); o4 = storage.WriteObject(p4new); var o6 = storage.WriteObject(p6); // The offset should be at the last file offset // because object length is over capacity o4.Should().Be(219); o6.Should().Be(343); ValidatePerson(storage.ReadObject(o4), p4new); ValidatePerson(storage.ReadObject(o6), p6); o2 = storage.WriteObject(p2new); o3 = storage.WriteObject(p3new); o2.Should().Be(94); o3.Should().Be(157); ValidatePerson(storage.ReadObject(o2), p2new); ValidatePerson(storage.ReadObject(o3), p3new); o2 = storage.UpdateObject(o2, p2newest); o2.Should().Be(94); ValidatePerson(storage.ReadObject(o2), p2newest); }