public void ReadWriteBuffer() { BlockStream s; byte[] r; byte[] w; byte[] c; s = new BlockStream(); r = new byte[10]; w = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; Assert.Equal(0, s.Read(r, 0, 10)); Assert.Equal(0, s.Length); Assert.Equal(0, s.Position); s.Write(w, 0, 10); Assert.Equal(10, s.Length); Assert.Equal(10, s.Position); s.Position = 0; Zero(r); s.Read(r, 0, 10); Assert.Equal(10, s.Length); Assert.Equal(10, s.Position); Assert.Equal(new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, r); s.Position = 5; Zero(r); Assert.Equal(5, s.Read(r, 0, 10)); Assert.Equal(new byte[] { 5, 6, 7, 8, 9, 0, 0, 0, 0, 0 }, r); s.Position = 5; Zero(r); Assert.Equal(5, s.Read(r, 5, 5)); Assert.Equal(new byte[] { 0, 0, 0, 0, 0, 5, 6, 7, 8, 9 }, r); s = new BlockStream(); s.Write(w, 5, 5); Assert.Equal(5, s.Length); Assert.Equal(5, s.Position); s.Position = 0; Zero(r); Assert.Equal(5, s.Read(r, 5, 5)); Assert.Equal(new byte[] { 0, 0, 0, 0, 0, 5, 6, 7, 8, 9 }, r); s = new BlockStream(); w = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; for (int i = 0; i < 100000; i++) { w[0] = (byte)(i << 24); w[1] = (byte)(i << 16); w[2] = (byte)(i << 8); w[3] = (byte)(i); s.Write(w, 0, 10); } Assert.Equal(10 * 100000, s.Position); Assert.Equal(10 * 100000, s.Length); s.Position = 0; c = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; for (int i = 0; i < 100000; i++) { Assert.Equal(10, s.Read(r, 0, 10)); c[0] = (byte)(i << 24); c[1] = (byte)(i << 16); c[2] = (byte)(i << 8); c[3] = (byte)(i); Assert.Equal(c, r); } }
public unsafe void Execute(uint stage, IService service) { // 1) We create the node common block. versionAddress = service.AllocationContext.AllocateBlock(); commonAddress = service.AllocationContext.AllocateBlock(); BPlusTree versionTS = new BPlusTree(service.AllocationContext.CreateEmptyBTree()); // Fill common block and write. Block commonBlock = new Block(service.BlockSize); fixed(byte *p = commonBlock.Data) { NodeCommonHeader *header = (NodeCommonHeader *)p; header->ChildrenBTree = service.AllocationContext.CreateEmptyBTree(); header->CurrentVersionAddress = versionAddress; header->CurrentVersionNumber = 0; header->HeaderMagic = NodeCommonHeader.Magic; header->ParentAddress = parentAddress; header->VersionsBTree = versionTS.RootAddress; } service.Write(BlockType.NodeHeaderBlock, commonAddress, commonBlock); // 2) We create the node default typed stream. Block tsblock = new Block(service.BlockSize); ulong tsBlock = service.AllocationContext.AllocateBlock(); fixed(byte *p = tsblock.Data) { TypedStreamHeader *header = (TypedStreamHeader *)p; header->ObjectsAddress = (defaultTSOptions & StreamOptions.SingleObject) == 0 ? service.AllocationContext.CreateEmptyBTree() : 0; header->Options = defaultTSOptions; header->ObjectSize = 0; int i; for (i = 0; i < defaultTSType.Length; i++) { header->Type[i] = defaultTSType[i]; } // Null terminate it. header->Type[i] = '\0'; } service.Write(BlockType.TypedStreamHeader, tsBlock, tsblock); // 3) We create the node version block. // Fill version block and write. Block versionBlock = new Block(service.BlockSize); fixed(byte *pp = versionBlock.Data) { NodeVersionHeader *header = (NodeVersionHeader *)pp; header->CreationTime = DateTime.Now; header->DefaultTypedStream = 0; header->HeaderMagic = NodeVersionHeader.Magic; header->ModifiedTime = DateTime.Now; header->NodeCommonAddress = commonAddress; header->StreamCount = 0; //< Is actually one but NodeHelper changes this. header->VersionNumber = 0; } // We must add default typed stream to block. NodeVersionHelper.AddTypedStream(tsBlock, defaultTSType, versionBlock); service.Write(BlockType.NodeHeaderBlock, versionAddress, versionBlock); // 4) We add to children tree. ObjectInfo info = childrenTree.Find(service, (uint)childName.GetHashCode()); if (info == null) { // We simply create a new object at address. ChildTag childTag = new ChildTag(); childTag.HashCode = childName.GetHashCode(); childTag.Add(childName, commonAddress); byte[] childData = Common.SerializeToArray(childTag); // We write it to block stream. BlockStream stream = service.AllocationContext.CreateBlockStream((ulong)childData.LongLength); stream.Write(childData); // We now add it to B+ tree. childrenTree.Add(service, new ObjectInfo((uint)childName.GetHashCode(), (ulong)childData.LongLength, stream.BaseAddress)); } else { // The index at hash already exists, we must add it, first read it. BlockStream stream = BlockStream.FromBase(info.Address, service); ChildTag childTag = Common.DeserializeFromArray(stream.Read(info.Size)) as ChildTag; // Steam not used anymore. stream.Deallocate(); // We modify child tag. childTag.Add(childName, commonAddress); byte[] childData = Common.SerializeToArray(childTag); // We must write it to new address. stream = service.AllocationContext.CreateBlockStream((ulong)childData.LongLength); stream.Write(childData); // Now we replace the data in tree. childrenTree.Replace(service, new ObjectInfo((uint)childName.GetHashCode(), (ulong)childData.LongLength, stream.BaseAddress)); } // 5) Add version to typed stream. VersionTag versionTag = new VersionTag((0).GetHashCode()); versionTag.Add(0, versionAddress); byte[] versionTagData = Common.SerializeToArray(versionTag); // Write to stream. BlockStream versionTagStream = service.AllocationContext.CreateBlockStream((ulong)versionTagData.LongLength); versionTagStream.Write(versionTagData); versionTS.Add(service, new ObjectInfo((uint)(0).GetHashCode(), (ulong)versionTagData.LongLength, versionTagStream.BaseAddress)); }
public void BlockStream_Basic() { BlockStream s; byte b; int cb; byte[] buf; byte[] cmp; //------------------------- cb = 1024; s = new BlockStream(); Assert.AreEqual(0, s.Length); Assert.AreEqual(0, s.Position); for (int i = 0; i < cb; i++) { s.WriteByte((byte)i); Assert.AreEqual((long)(i + 1), s.Position); Assert.AreEqual((long)(i + 1), s.Length); } s.Position = 0; for (int i = 0; i < cb; i++) { b = (byte)s.ReadByte(); Assert.AreEqual((byte)i, b); Assert.AreEqual((long)(i + 1), s.Position); Assert.AreEqual(cb, s.Length); } cmp = new byte[cb]; for (int i = 0; i < cb; i++) { cmp[i] = (byte)i; } buf = new byte[cb]; s.Position = 0; s.Read(buf, 0, cb); CollectionAssert.AreEqual(cmp, buf); Assert.AreEqual((long)cb, s.Position); Assert.AreEqual((long)cb, s.Length); //------------------------- cb = 256; s = new BlockStream(cb); Assert.AreEqual(0, s.Length); Assert.AreEqual(0, s.Position); for (int i = 0; i < cb; i++) { s.WriteByte((byte)i); Assert.AreEqual((long)(i + 1), s.Position); Assert.AreEqual((long)(i + 1), s.Length); } s.Position = 0; for (int i = 0; i < cb; i++) { b = (byte)s.ReadByte(); Assert.AreEqual((byte)i, b); Assert.AreEqual((long)(i + 1), s.Position); Assert.AreEqual(cb, s.Length); } cmp = new byte[cb]; for (int i = 0; i < cb; i++) { cmp[i] = (byte)i; } buf = new byte[cb]; s.Position = 0; s.Read(buf, 0, cb); CollectionAssert.AreEqual(cmp, buf); Assert.AreEqual((long)cb, s.Position); Assert.AreEqual((long)cb, s.Length); //------------------------- cb = 3 * 256 + 1; s = new BlockStream(cb, 256); Assert.AreEqual(0, s.Length); Assert.AreEqual(0, s.Position); for (int i = 0; i < cb; i++) { s.WriteByte((byte)i); Assert.AreEqual((long)(i + 1), s.Position); Assert.AreEqual((long)(i + 1), s.Length); } s.Position = 0; for (int i = 0; i < cb; i++) { b = (byte)s.ReadByte(); Assert.AreEqual((byte)i, b); Assert.AreEqual((long)(i + 1), s.Position); Assert.AreEqual(cb, s.Length); } cmp = new byte[cb]; for (int i = 0; i < cb; i++) { cmp[i] = (byte)i; } buf = new byte[cb]; s.Position = 0; s.Read(buf, 0, cb); CollectionAssert.AreEqual(cmp, buf); Assert.AreEqual((long)cb, s.Position); Assert.AreEqual((long)cb, s.Length); //------------------------- cb = 300; s = new BlockStream(new Block(cb / 3), new Block(cb / 3), new Block(cb / 3)); Assert.AreEqual(cb, s.Length); Assert.AreEqual(0, s.Position); for (int i = 0; i < cb; i++) { s.WriteByte((byte)i); Assert.AreEqual((long)(i + 1), s.Position); } s.Position = 0; for (int i = 0; i < cb; i++) { b = (byte)s.ReadByte(); Assert.AreEqual((byte)i, b); Assert.AreEqual((long)(i + 1), s.Position); } cmp = new byte[cb]; for (int i = 0; i < cb; i++) { cmp[i] = (byte)i; } buf = new byte[cb]; s.Position = 0; s.Read(buf, 0, cb); CollectionAssert.AreEqual(cmp, buf); Assert.AreEqual((long)cb, s.Position); //------------------------- cb = 300; s = new BlockStream(new BlockArray(new Block[] { new Block(cb / 3), new Block(cb / 3), new Block(cb / 3) })); Assert.AreEqual(cb, s.Length); Assert.AreEqual(0, s.Position); for (int i = 0; i < cb; i++) { s.WriteByte((byte)i); Assert.AreEqual((long)(i + 1), s.Position); } s.Position = 0; for (int i = 0; i < cb; i++) { b = (byte)s.ReadByte(); Assert.AreEqual((byte)i, b); Assert.AreEqual((long)(i + 1), s.Position); } cmp = new byte[cb]; for (int i = 0; i < cb; i++) { cmp[i] = (byte)i; } buf = new byte[cb]; s.Position = 0; s.Read(buf, 0, cb); CollectionAssert.AreEqual(cmp, buf); Assert.AreEqual((long)cb, s.Position); }
public void BlockStream_Seek() { BlockStream s = new BlockStream(); byte[] r = new byte[10]; byte[] w = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; byte[] c = new byte[] { 0, 0, 0, 0, 4, 5, 6, 7, 8, 9 }; for (int i = 0; i < 100000; i++) { w[0] = (byte)(i << 24); w[1] = (byte)(i << 16); w[2] = (byte)(i << 8); w[3] = (byte)(i); s.Write(w, 0, 10); } for (int i = 0; i < 100000; i++) { int pos = i; c[0] = (byte)(pos << 24); c[1] = (byte)(pos << 16); c[2] = (byte)(pos << 8); c[3] = (byte)(pos); s.Seek(pos * 10, SeekOrigin.Begin); Assert.AreEqual((long)(pos * 10), s.Position); Assert.AreEqual(10, s.Read(r, 0, 10)); CollectionAssert.AreEqual(c, r); } for (int i = 0; i < 100000; i++) { int pos = i; c[0] = (byte)(pos << 24); c[1] = (byte)(pos << 16); c[2] = (byte)(pos << 8); c[3] = (byte)(pos); s.Position = 50000 * 10; s.Seek(pos * 10 - 50000 * 10, SeekOrigin.Current); Assert.AreEqual((long)(pos * 10), s.Position); Assert.AreEqual(10, s.Read(r, 0, 10)); CollectionAssert.AreEqual(c, r); } for (int i = 0; i < 100000; i++) { int pos = i; c[0] = (byte)(pos << 24); c[1] = (byte)(pos << 16); c[2] = (byte)(pos << 8); c[3] = (byte)(pos); s.Seek(-(100000 * 10 - pos * 10), SeekOrigin.End); Assert.AreEqual((long)(pos * 10), s.Position); Assert.AreEqual(10, s.Read(r, 0, 10)); CollectionAssert.AreEqual(c, r); } }
public unsafe void Execute(uint stage, IService service) { ulong versionAddress = service.AllocationContext.AllocateBlock(); // 1) We first create new version node. Block versionBlock = new Block(service.BlockSize); fixed(byte *p = versionBlock.Data) { NodeVersionHeader *header = (NodeVersionHeader *)p; header->CreationTime = DateTime.Now; header->DefaultTypedStream = 0; header->HeaderMagic = NodeVersionHeader.Magic; header->ModifiedTime = DateTime.Now; header->NodeCommonAddress = commonAddress; header->StreamCount = 0; //< For now 0. header->VersionNumber = version; } // 2) We create default TS. ulong defaultTSAddress = service.AllocationContext.AllocateBlock(); Block block = new Block(service.BlockSize); fixed(byte *p = block.Data) { TypedStreamHeader *header = (TypedStreamHeader *)p; header->ObjectsAddress = (defaultTSOptions & StreamOptions.SingleObject) != 0 ? 0 : service.AllocationContext.CreateEmptyBTree(); header->ObjectSize = 0; header->Options = defaultTSOptions; // Copy the name. int i; for (i = 0; i < defaultTSType.Length; i++) { header->Type[i] = defaultTSType[i]; } header->Type[i] = '\0'; } service.Write(BlockType.TypedStreamHeader, defaultTSAddress, block); // 3) We add the default typed stream and write it. NodeVersionHelper.AddTypedStream(defaultTSAddress, defaultTSType, versionBlock); service.Write(BlockType.NodeHeaderBlock, versionAddress, versionBlock); // 4) And finnaly add to versions. ObjectInfo info = versionTree.Find(service, (uint)version.GetHashCode()); if (info == null) { // Create block stream. VersionTag versionTag = new VersionTag(version.GetHashCode()); versionTag.Add(version, versionAddress); byte[] versionTagData = Common.SerializeToArray(versionTag); BlockStream stream = service.AllocationContext.CreateBlockStream((ulong)versionTagData.LongLength); // Write the stream. stream.Write(versionTagData); // And to B+ tree. versionTree.Add(service, new ObjectInfo((uint)version.GetHashCode(), (ulong)versionTagData.LongLength, stream.BaseAddress));; } else { // We first create appropriate VersionTag and kill the stream. BlockStream stream = BlockStream.FromBase(info.Address, service); VersionTag versionTag = Common.DeserializeFromArray(stream.Read(info.Size)) as VersionTag; versionTag.Add(version, versionAddress); stream.Deallocate(); // We write a new version tag. byte[] versionTagData = Common.SerializeToArray(versionTag); stream = service.AllocationContext.CreateBlockStream((ulong)versionTagData.LongLength); stream.Write(versionTagData); // We replace in B+ tree. versionTree.Replace(service, new ObjectInfo((uint)version.GetHashCode(), (ulong)versionTagData.LongLength, versionAddress)); } // 5) The new version is replaced in common. block = service.Read(BlockType.NodeHeaderBlock, commonAddress); fixed(byte *p = block.Data) { NodeCommonHeader *header = (NodeCommonHeader *)p; header->CurrentVersionNumber = version; header->CurrentVersionAddress = versionAddress; } service.Write(BlockType.NodeHeaderBlock, commonAddress, block); }