Ejemplo n.º 1
0
        /// <summary>
        /// Unpack this item for DeSerialization from Stream
        /// </summary>
        /// <param name="parent"></param>
        /// <param name="reader"></param>
        public virtual void Unpack(IInternalPersistent parent, System.IO.BinaryReader reader)
        {
            bool?r = CollectionOnDisk.ReadPersistentData(parent, reader, ref Key);

            if (r == null)
            {
                if (((BTreeAlgorithm)parent).onKeyUnpack != null)
                {
                    Key = ((BTreeAlgorithm)parent).onKeyUnpack(reader);
                }
                else
                {
                    throw new SopException("Can't Deserialize Custom persisted 'Key'.");
                }
            }
            if (Value == null)
            {
                var f = (File.File)InternalPersistent.GetParent(parent, typeof(File.File));
                Value = new ItemOnDisk(f.DataBlockSize);
            }
            bool valueIsReference = reader.ReadBoolean();

            if (valueIsReference)
            {
                Value.DiskBuffer.DataAddress = reader.ReadInt64();
            }
            else
            {
                object o = Value;
                CollectionOnDisk.ReadPersistentData(parent, reader, ref o);
                Value = (ItemOnDisk)o;
                if (Value.DataIsUserDefined && ((BTreeAlgorithm)parent).onValueUnpack != null)
                {
                    Value.Data = ((BTreeAlgorithm)parent).onValueUnpack(reader);
                }
            }
            IsDirty = false;
        }
Ejemplo n.º 2
0
        /// <summary>
        /// DeSerialize
        /// </summary>
        /// <param name="parent"></param>
        /// <param name="reader"></param>
        public override void Unpack(IInternalPersistent parent,
                                    BinaryReader reader)
        {
            System.IO.BinaryReader binaryReader = reader;
            long l = binaryReader.ReadInt64();

            if (l >= 0)
            {
                DiskBuffer.DataAddress = l;
            }
            long cnt = binaryReader.ReadInt64();
            long saa = binaryReader.ReadInt64();

            if ((Count > 0 && cnt == 0) ||
                StartAllocatableAddress > 0 && saa == 0)
            {
                binaryReader.ReadInt64();
                binaryReader.ReadInt64();
                binaryReader.ReadInt64();
                binaryReader.ReadInt64();
                if (reader.ReadBoolean())
                {
                    var rs = new DeletedBlockInfo();
                    rs.Unpack(parent, reader);
                }
                return;
            }
            Count = cnt;                   //BinaryReader.ReadInt32();
            StartAllocatableAddress = saa; // BinaryReader.ReadInt64();
            EndAllocatableAddress   = binaryReader.ReadInt64();
            NextAllocatableAddress  = binaryReader.ReadInt64();
            long          obh = binaryReader.ReadInt64();
            long          obt = binaryReader.ReadInt64();
            DataBlockSize dataBlockSize;

            if (parent != null)
            {
                File.File f = (File.File)InternalPersistent.GetParent(parent, typeof(File.File), true);
                dataBlockSize = f.DataBlockSize;
            }
            else
            {
                dataBlockSize = (DataBlockSize)DiskBuffer.Length;
            }
            if (obh >= 0)
            {
                OccupiedBlocksHead             = new Sop.DataBlock(dataBlockSize);
                OccupiedBlocksHead.DataAddress = obh;
            }
            else if (OccupiedBlocksHead != null)
            {
                OccupiedBlocksHead = null;
            }
            if (obt >= 0)
            {
                OccupiedBlocksTail             = new Sop.DataBlock(dataBlockSize);
                OccupiedBlocksTail.DataAddress = obt;
            }
            else if (OccupiedBlocksTail != null)
            {
                OccupiedBlocksTail = null;
            }

            if (reader.ReadBoolean())
            {
                RecycledSegment = new DeletedBlockInfo();
                RecycledSegment.Unpack(parent, reader);
                RecycledSegmentBeforeTransaction = (DeletedBlockInfo)RecycledSegment.Clone();
            }
        }
        /// <summary>
        /// Serialize Object in preparation for saving to disk/virtual store
        /// </summary>
        /// <param name="parent"></param>
        /// <param name="objectToSerialize"></param>
        /// <param name="writer"></param>
        /// <param name="itemType"> </param>
        public static void WritePersistentData(
            IInternalPersistent parent,
            object objectToSerialize,
            BinaryWriter writer,
            ItemType itemType
            )
        {
            if (objectToSerialize != null)
            {
                long proxyRealDataAddress = 0;
                #region process proxy object
                if (objectToSerialize is Sop.IProxyObject)
                {
                    if (((Sop.IProxyObject)objectToSerialize).RealObject != null)
                    {
                        long.TryParse(objectToSerialize.ToString(), out proxyRealDataAddress);
                        objectToSerialize = ((Sop.IProxyObject)objectToSerialize).RealObject;
                    }
                    else
                    {
                        string s = objectToSerialize.ToString();
                        long   dataAddress;
                        if (long.TryParse(s, out dataAddress))
                        {
                            // save object's value
                            //** save persistence method used so we can deserialize
                            writer.Write((byte)PersistenceType.Custom);

                            //** save Value type so we can deserialize to the same type.
                            const int objectTypeId = (int)BuiltinTypes.SortedDictionaryOnDisk;
                            writer.Write(objectTypeId);

                            //** reserve space for the data size!
                            writer.Write(40);
                            writer.Write(dataAddress);
                            // set to null to prevent code
                            objectToSerialize = null;
                        }
                        else
                        {
                            throw new InvalidOperationException(
                                      string.Format("Unknown 'objectToSerialize' ({0}) type.",
                                                    objectToSerialize.GetType().ToString()));
                        }
                    }
                }
                #endregion
                if (objectToSerialize is IInternalPersistent)
                {
                    // save object's value
                    //** save persistence method used so we can deserialize
                    writer.Write((byte)PersistenceType.Custom);

                    var file = (File.IFile)InternalPersistent.GetParent(parent, typeof(File.File));
                    //** save Value type so we can deserialize to the same type.
                    int objectTypeId = file.Server.TypeStore.RegisterType(objectToSerialize);
                    writer.Write(objectTypeId);

                    //** save data value size and data value
                    int           posn      = 0;
                    Sop.DataBlock posnBlock = null;
                    if (objectToSerialize is BTreeNodeOnDisk)
                    {
                        posn      = (int)writer.BaseStream.Position;
                        posnBlock = ((OnDiskBinaryWriter)writer).DataBlock;
                    }
                    //** reserve space for the data size!
                    writer.Write(40);

                    if (objectToSerialize is SortedDictionaryOnDisk)
                    {
                        var sdod = (SortedDictionaryOnDisk)objectToSerialize;
                        if (proxyRealDataAddress > 0)
                        {
                            writer.Write(proxyRealDataAddress);
                        }
                        else
                        {
                            if (sdod.DataAddress == -1)
                            {
                                sdod.Flush();
                            }
                            writer.Write(sdod.DataAddress);
                        }
                    }
                    else
                    {
                        ((IInternalPersistent)objectToSerialize).Pack(parent, writer);
                    }

                    //** save data value size and data value
                    var bTreeNodeOnDisk = objectToSerialize as BTreeNodeOnDisk;
                    if (bTreeNodeOnDisk != null)
                    {
                        int cm = (bTreeNodeOnDisk).DiskBuffer.CountMembers(true);
                        if (cm > byte.MaxValue)
                        {
                            cm = byte.MaxValue;
                        }
                        posnBlock.Data[posn] = (byte)cm;
                    }
                }
                else if (IsSimpleType(objectToSerialize))
                {
                    writer.Write((byte)PersistenceType.SimpleType);
                    WriteSimpleType(objectToSerialize, writer);
                }
                else if (objectToSerialize is string)
                {
                    writer.Write((byte)PersistenceType.String);
                    var s = (string)objectToSerialize;
                    writer.Write(s);
                }
                else if (objectToSerialize is byte[])
                {
                    writer.Write((byte)PersistenceType.ByteArray);
                    var rawBytes = (byte[])objectToSerialize;
                    writer.Write(rawBytes.Length);
                    writer.Write(rawBytes);
                }
                else if (itemType == ItemType.Key &&
                         parent is BTreeAlgorithm &&
                         ((BTreeAlgorithm)parent).onKeyPack != null)
                {
                    // save object's value
                    //** save persistence method used so we can deserialize
                    writer.Write((byte)PersistenceType.Custom);
                    //** save Value type so we can deserialize to the same type.
                    var file         = (File.IFile)InternalPersistent.GetParent(parent, typeof(File.File));
                    int objectTypeId = file.Server.TypeStore.RegisterType(objectToSerialize);
                    writer.Write(objectTypeId);
                    //** reserve space for the data size!
                    writer.Write(40);
                    //((Algorithm.BTreeAlgorithm)Parent).onKeyPack(Writer, ObjectToSerialize);

                    int sizeOccupied = ((OnDiskBinaryWriter)writer).DataBlock.SizeOccupied;
                    var db           = ((OnDiskBinaryWriter)writer).DataBlock;

                    int posn = (int)writer.BaseStream.Position;
                    ((BTreeAlgorithm)parent).onKeyPack(writer, objectToSerialize);

                    //** write to SOP disk buffer if data wasn't written to it yet...
                    if (db == ((OnDiskBinaryWriter)writer).DataBlock &&
                        sizeOccupied == ((OnDiskBinaryWriter)writer).DataBlock.SizeOccupied)
                    {
                        ((OnDiskBinaryWriter)writer).write(posn, (int)writer.BaseStream.Position);
                    }
                }
                else if (itemType == ItemType.Value &&
                         parent is BTreeAlgorithm &&
                         ((BTreeAlgorithm)parent).onValuePack != null)
                {
                    // save object's value
                    //** save persistence method used so we can deserialize
                    writer.Write((byte)PersistenceType.Custom);
                    //** save Value type so we can deserialize to the same type.
                    var file         = (File.IFile)InternalPersistent.GetParent(parent, typeof(File.File));
                    int objectTypeId = file.Server.TypeStore.RegisterType(objectToSerialize);
                    writer.Write(objectTypeId);
                    //** reserve space for the data size!
                    writer.Write(40);
                    //((Algorithm.BTreeAlgorithm)Parent).onValuePack(Writer, ObjectToSerialize);

                    int           sizeOccupied = ((OnDiskBinaryWriter)writer).DataBlock.SizeOccupied;
                    Sop.DataBlock db           = ((OnDiskBinaryWriter)writer).DataBlock;

                    int posn = (int)writer.BaseStream.Position;
                    ((BTreeAlgorithm)parent).onValuePack(writer, objectToSerialize);
                    //** write to SOP disk buffer if data wasn't written to it yet...
                    if (db == ((OnDiskBinaryWriter)writer).DataBlock &&
                        sizeOccupied == ((OnDiskBinaryWriter)writer).DataBlock.SizeOccupied)
                    {
                        ((OnDiskBinaryWriter)writer).write(posn, (int)writer.BaseStream.Position);
                    }
                }
                else if (objectToSerialize is IPersistent)
                {
                    // save object's value
                    //** save persistence method used so we can deserialize
                    writer.Write((byte)PersistenceType.Custom);
                    //** save Value type so we can deserialize to the same type.
                    var file         = (File.IFile)InternalPersistent.GetParent(parent, typeof(File.File));
                    int objectTypeId = file.Server.TypeStore.RegisterType(objectToSerialize);
                    writer.Write(objectTypeId);
                    //** reserve space for the data size!
                    writer.Write(40);

                    //** save data value size and data value
                    int           posn      = (int)writer.BaseStream.Position;
                    Sop.DataBlock posnBlock = ((OnDiskBinaryWriter)writer).DataBlock;
                    ((IPersistent)objectToSerialize).Pack(writer);
                    int hintSize = ((IPersistent)objectToSerialize).HintSizeOnDisk;
                    if (hintSize > 0)
                    {
                        int sizeWritten = posnBlock.GetSizeOccupied(posn);
                        if (hintSize > sizeWritten)
                        {
                            var b = new byte[hintSize - sizeWritten];
                            writer.Write(b);
                        }
                    }
                }
                else if (objectToSerialize != null)
                {
                    // expects Data to be Binary Serializable
                    writer.Write((byte)PersistenceType.BinarySerialized);
                    int si  = (int)writer.BaseStream.Position;
                    var ser = new BinaryFormatter();
                    ser.Serialize(writer.BaseStream, objectToSerialize);
                    ((OnDiskBinaryWriter)writer).write(si, (int)writer.BaseStream.Position);
                }
            }
            else
            {
                writer.Write((byte)PersistenceType.Null);
            }

            //** mark unused next block as unoccupied so it and its linked blocks can be recycled..
            var w = writer as OnDiskBinaryWriter;
            if (w == null)
            {
                return;
            }
            if (w.DataBlock.SizeAvailable > 0 && w.DataBlock.Next != null && w.DataBlock.Next.SizeOccupied > 0)
            {
                w.DataBlock.Next.SizeOccupied = 0;
            }
        }
        /// <summary>
        /// Read/Deserialize Persisted object
        /// </summary>
        /// <param name="parent"> </param>
        /// <param name="reader"></param>
        /// <param name="itemType"> </param>
        /// <param name="deSerializedObject">DeSerializedObject will contain the Deserialized object (returns true),
        /// else the size of the Custom Persisted object (returns false).
        /// </param>
        /// <returns>true if Deserialized,
        ///         false if End of Stream,
        ///         null if object was Custom Persisted and was not read</returns>
        public static bool?ReadPersistentData(
            IInternalPersistent parent,
            BinaryReader reader,
            ref object deSerializedObject,
            ItemType itemType = ItemType.Default
            )
        {
            if (reader.PeekChar() == -1)
            {
                //** end of stream, no more object to deserialize...
                deSerializedObject = 0;
                return(false);
            }
            var file = (File.File)InternalPersistent.GetParent(parent, typeof(File.File));
            var t    = (PersistenceType)reader.ReadByte();
            int size;

            switch (t)
            {
            case PersistenceType.Custom:
                //** get the type of object to be deserialized
                int objectTypeId = reader.ReadInt32();
                //** get the size of object
                size = reader.ReadInt32();
                if (size > 0)
                {
                    if (deSerializedObject == null)
                    {
                        deSerializedObject = file.Server.TypeStore.CreateInstance(file.Transaction, objectTypeId,
                                                                                  new[]
                        {
                            new KeyValuePair
                            <string, object>(
                                "File", file)
                        });
                    }
                    if (deSerializedObject is IInternalPersistent)
                    {
                        if (deSerializedObject is ICollectionOnDisk &&
                            ((ICollectionOnDisk)deSerializedObject).File == null)
                        {
                            ((ICollectionOnDisk)deSerializedObject).File = file;
                        }
                        else if (deSerializedObject is File.File)
                        {
                            if (parent is ICollectionOnDisk)
                            {
                                //((File.File)deSerializedObject).Profile = new Profile(file.Profile);
                                ((File.File)deSerializedObject).Profile.DataBlockSize = file.Profile.DataBlockSize;
                            }
                            if (((File.File)deSerializedObject).Parent == null)
                            {
                                if (parent is ICollectionOnDisk)
                                {
                                    ((File.File)deSerializedObject).Parent = (ICollectionOnDisk)parent;
                                }
                                ((File.File)deSerializedObject).Server = file.Server;
                            }
                        }
                        if (deSerializedObject is SortedDictionaryOnDisk)
                        {
                            var bTreeAlgorithm = parent as BTreeAlgorithm;
                            if (bTreeAlgorithm != null)
                            {
                                if ((bTreeAlgorithm).onInnerMemberKeyPack != null)
                                {
                                    ((SortedDictionaryOnDisk)deSerializedObject).BTreeAlgorithm.onKeyPack =
                                        (bTreeAlgorithm).onInnerMemberKeyPack;
                                }
                                if ((bTreeAlgorithm).onInnerMemberKeyUnpack != null)
                                {
                                    ((SortedDictionaryOnDisk)deSerializedObject).BTreeAlgorithm.onKeyUnpack =
                                        (bTreeAlgorithm).onInnerMemberKeyUnpack;
                                }

                                if ((bTreeAlgorithm).onInnerMemberValuePack != null)
                                {
                                    ((SortedDictionaryOnDisk)deSerializedObject).BTreeAlgorithm.onValuePack =
                                        (bTreeAlgorithm).onInnerMemberValuePack;
                                }
                                if ((bTreeAlgorithm).onInnerMemberValueUnpack != null)
                                {
                                    ((SortedDictionaryOnDisk)deSerializedObject).BTreeAlgorithm.onValueUnpack =
                                        (bTreeAlgorithm).onInnerMemberValueUnpack;
                                }
                            }
                            var sdod = (SortedDictionaryOnDisk)deSerializedObject;
                            sdod.DataAddress = reader.ReadInt64();
                            sdod.Open();
                        }
                        else
                        {
                            ((IInternalPersistent)deSerializedObject).Unpack(parent, reader);
                        }
                        return(true);
                    }
                    //** Object(with ObjectTypeID) is User defined Type. Caller code should DeSerialize it...
                    deSerializedObject = null;
                    return(null);
                }
                if (size == 0)
                {
                    return(true);
                }
                //** end of stream, no more object to deserialize...
                deSerializedObject = 0;
                return(false);

            case PersistenceType.SimpleType:
                deSerializedObject = ReadSimpleType(reader);
                break;

            case PersistenceType.String:
                deSerializedObject = reader.ReadString();
                break;

            case PersistenceType.ByteArray:
                size = reader.ReadInt32();
                deSerializedObject = reader.ReadBytes(size);
                break;

            case PersistenceType.BinarySerialized:
                var ser =
                    new BinaryFormatter();
                deSerializedObject = ser.Deserialize(reader.BaseStream);
                break;

            case PersistenceType.Null:
                deSerializedObject = null;
                break;
            }
            return(true);
        }
Ejemplo n.º 5
0
 /// <summary>
 /// Traverse the Parent hierarchy and look for a Parent of a given Type.
 /// Example, one can look for the "File" container of a Collection or a Parent
 /// Collection of a Collection and so on and so forth..
 /// </summary>
 /// <param name="parentType"></param>
 /// <returns></returns>
 public virtual IInternalPersistent GetParent(Type parentType)
 {
     return(InternalPersistent.GetParent(Parent, parentType));
 }