Пример #1
0
        public override PagedIndexQueryResult MergeResults(IList <PagedIndexQueryResult> partialResults)
        {
            PagedIndexQueryResult finalResult = default(PagedIndexQueryResult);

            if (partialResults == null || partialResults.Count == 0)
            {
                return(finalResult);
            }

            // We have partialResults to process
            BaseComparer baseComparer = null;
            ByteArrayEqualityComparer byteArrayEqualityComparer = new ByteArrayEqualityComparer();
            Dictionary <byte[] /*IndexId*/, IndexHeader /*IndexHeader*/> completeIndexIdIndexHeaderMapping =
                new Dictionary <byte[], IndexHeader>(byteArrayEqualityComparer);

            // resultVer required to determine if server is correctly performing paging logic
            int resultVer = 0;

            if (partialResults.Count == 1)
            {
                #region  Just one cluster was targeted, so no need to merge anything

                finalResult = partialResults[0];
                if (finalResult != null)
                {
                    resultVer = finalResult.CurrentVersion;
                }

                #endregion
            }
            else
            {
                #region  More than one clusters was targeted

                List <ResultItem> completeResultItemList = new List <ResultItem>();
                GroupByResult     completeGroupByResult  = new GroupByResult(null);
                int           totalCount             = 0;
                int           pageableItemCount      = 0;
                StringBuilder exceptionStringBuilder = new StringBuilder();
                bool          indexCapSet            = false;
                int           indexCap = 0;

                foreach (PagedIndexQueryResult partialResult in partialResults)
                {
                    if (partialResult != null)
                    {
                        #region Update resultVer

                        if (resultVer == 0)
                        {
                            resultVer = partialResult.CurrentVersion;
                        }

                        #endregion

                        #region Assign IndexCap

                        if (!indexCapSet)
                        {
                            indexCap    = partialResult.IndexCap;
                            indexCapSet = true;
                        }

                        #endregion

                        #region Compute TotalCount

                        totalCount += partialResult.TotalCount;

                        #endregion

                        #region Compute PageableItemCount

                        if (GetPageableItemCount)
                        {
                            pageableItemCount += partialResult.AdditionalAvailableItemCount;
                        }

                        #endregion

                        #region Merge Results

                        if ((partialResult.ResultItemList != null && partialResult.ResultItemList.Count > 0) ||
                            (partialResult.GroupByResult != null && partialResult.GroupByResult.Count > 0))
                        {
                            if (baseComparer == null)
                            {
                                baseComparer = new BaseComparer(partialResult.IsTagPrimarySort,
                                                                partialResult.SortFieldName,
                                                                partialResult.SortOrderList);
                                completeGroupByResult = new GroupByResult(baseComparer);
                            }

                            if (GroupBy == null)
                            {
                                MergeAlgo.MergeItemLists(ref completeResultItemList,
                                                         partialResult.ResultItemList,
                                                         MaxMergeCount,
                                                         baseComparer);
                            }
                            else
                            {
                                MergeAlgo.MergeGroupResult(ref completeGroupByResult,
                                                           partialResult.GroupByResult,
                                                           MaxMergeCount,
                                                           baseComparer);
                            }
                        }
                        #endregion

                        #region Update IndexIdIndexHeaderMapping

                        if (GetIndexHeaderType != GetIndexHeaderType.None &&
                            partialResult.IndexIdIndexHeaderMapping != null &&
                            partialResult.IndexIdIndexHeaderMapping.Count > 0)
                        {
                            foreach (KeyValuePair <byte[], IndexHeader> kvp in partialResult.IndexIdIndexHeaderMapping)
                            {
                                if (!completeIndexIdIndexHeaderMapping.ContainsKey(kvp.Key))
                                {
                                    completeIndexIdIndexHeaderMapping.Add(kvp.Key, kvp.Value);
                                }
                            }
                        }

                        #endregion

                        #region Update exceptionInfo

                        if (!String.IsNullOrEmpty(partialResult.ExceptionInfo))
                        {
                            exceptionStringBuilder.Append(partialResult.ExceptionInfo);
                            exceptionStringBuilder.Append(" ");
                        }

                        #endregion
                    }
                }

                #region Create FinalResult

                finalResult = new PagedIndexQueryResult
                {
                    ResultItemList = completeResultItemList,
                    GroupByResult  = completeGroupByResult,
                    TotalCount     = totalCount,
                    AdditionalAvailableItemCount = pageableItemCount,
                    IndexCap = indexCap,
                };

                //Assign sort fields for use in GroupBy remote queries
                if (baseComparer != null)
                {
                    finalResult.IsTagPrimarySort = baseComparer.IsTagPrimarySort;
                    finalResult.SortFieldName    = baseComparer.SortFieldName;
                    finalResult.SortOrderList    = baseComparer.SortOrderList;
                }

                if (GetIndexHeaderType != GetIndexHeaderType.None && completeIndexIdIndexHeaderMapping.Count > 0)
                {
                    finalResult.IndexIdIndexHeaderMapping = completeIndexIdIndexHeaderMapping;
                }

                if (exceptionStringBuilder.Length > 0)
                {
                    finalResult.ExceptionInfo = exceptionStringBuilder.ToString();
                }

                #endregion

                #endregion
            }

            #region Determine whether client side paging is required

            bool performClientSidePaging;
            if (resultVer < PagedIndexQueryResult.CORRECT_SERVERSIDE_PAGING_LOGIC_VERSION)
            {
                // this.ClientSidePaging cannot be trusted
                performClientSidePaging = numClustersInGroup > 1 && PageNum != 0;
            }
            else
            {
                // this.ClientSidePaging can be trusted
                performClientSidePaging = ClientSidePaging && PageNum != 0;
            }

            #endregion

            #region Perform Paging and Update IndexIdIndexHeaderMapping if required

            if (performClientSidePaging && finalResult != null)
            {
                #region Paging Logic

                int start = (PageNum - 1) * PageSize;
                if (GroupBy == null)
                {
                    int end = (PageNum * PageSize) < finalResult.ResultItemList.Count ? (PageNum * PageSize) : finalResult.ResultItemList.Count;
                    List <ResultItem> filteredResultItemList = new List <ResultItem>();
                    for (int i = start; i < end; i++)
                    {
                        filteredResultItemList.Add(finalResult.ResultItemList[i]);
                    }
                    finalResult.ResultItemList = filteredResultItemList;
                }
                else if (finalResult.GroupByResult != null && finalResult.GroupByResult.Count > 0)
                {
                    int           end = (PageNum * PageSize) < finalResult.GroupByResult.Count ? (PageNum * PageSize) : finalResult.GroupByResult.Count;
                    GroupByResult filteredGroupByResult = new GroupByResult(baseComparer);
                    for (int i = start; i < end; i++)
                    {
                        filteredGroupByResult.Add(finalResult.GroupByResult[i].CompositeKey, finalResult.GroupByResult[i]);
                    }
                    finalResult.GroupByResult = filteredGroupByResult;
                }

                #endregion

                #region Update IndexIdIndexHeaderMapping to only include metadata relevant after paging

                if (partialResults.Count != 1 && GetIndexHeaderType == GetIndexHeaderType.ResultItemsIndexIds && completeIndexIdIndexHeaderMapping.Count > 0)
                {
                    Dictionary <byte[] /*IndexId*/, IndexHeader /*IndexHeader*/> filteredIndexIdIndexHeaderMapping =
                        new Dictionary <byte[], IndexHeader>(byteArrayEqualityComparer);
                    if (GroupBy == null)
                    {
                        foreach (ResultItem resultItem in finalResult.ResultItemList)
                        {
                            if (!filteredIndexIdIndexHeaderMapping.ContainsKey(resultItem.IndexId))
                            {
                                filteredIndexIdIndexHeaderMapping.Add(resultItem.IndexId, completeIndexIdIndexHeaderMapping[resultItem.IndexId]);
                            }
                        }
                    }
                    else if (finalResult.GroupByResult != null && finalResult.GroupByResult.Count > 0)
                    {
                        foreach (ResultItemBag resultItemBag in finalResult.GroupByResult)
                        {
                            for (int i = 0; i < resultItemBag.Count; i++)
                            {
                                ResultItem resultItem = resultItemBag[i];
                                if (!filteredIndexIdIndexHeaderMapping.ContainsKey(resultItem.IndexId))
                                {
                                    filteredIndexIdIndexHeaderMapping.Add(resultItem.IndexId, completeIndexIdIndexHeaderMapping[resultItem.IndexId]);
                                }
                            }
                        }
                    }
                    finalResult.IndexIdIndexHeaderMapping = filteredIndexIdIndexHeaderMapping.Count > 0 ? filteredIndexIdIndexHeaderMapping : null;
                }

                #endregion
            }

            #endregion

            return(finalResult);
        }
Пример #2
0
        public override void Deserialize(IPrimitiveReader reader, int version)
        {
            //ResultItemList
            int listCount = reader.ReadInt32();
            ResultItemList = new List<ResultItem>(listCount);
            if (listCount > 0)
            {
                ResultItem resultItem;
                for (int i = 0; i < listCount; i++)
                {
                    resultItem = new ResultItem();
                    resultItem.Deserialize(reader);
                    ResultItemList.Add(resultItem);
                }
            }

            //IndexIdIndexHeaderMapping
            ushort count = reader.ReadUInt16();
            if (count > 0)
            {
                IndexIdIndexHeaderMapping = new Dictionary<byte[], IndexHeader>(count, new ByteArrayEqualityComparer());
                byte[] indexId;
                IndexHeader indexHeader;
                ushort len;

                for (ushort i = 0; i < count; i++)
                {
                    len = reader.ReadUInt16();
                    indexId = null;
                    if (len > 0)
                    {
                        indexId = reader.ReadBytes(len);
                    }
                    indexHeader = new IndexHeader();
                    Serializer.Deserialize(reader.BaseStream, indexHeader);

                    IndexIdIndexHeaderMapping.Add(indexId, indexHeader);
                }
            }

            //TotalCount
            TotalCount = reader.ReadInt32();

            //IsTagPrimarySort
            IsTagPrimarySort = reader.ReadBoolean();

            //SortFieldName
            SortFieldName = reader.ReadString();

            //SortOrderList
            count = reader.ReadUInt16();
            SortOrderList = new List<SortOrder>(count);
            SortOrder sortOrder;
            for (int i = 0; i < count; i++)
            {
                sortOrder = new SortOrder();
                sortOrder.Deserialize(reader);
                SortOrderList.Add(sortOrder);
            }

            //ExceptionInfo
            ExceptionInfo = reader.ReadString();

            //AdditionalAvailableItemCount
            AdditionalAvailableItemCount = reader.ReadInt32();
        }
		public void Deserialize(MySpace.Common.IO.IPrimitiveReader reader, int version)
		{
            //IndexExists
            indexExists = reader.ReadBoolean();

            //IndexSize
            indexSize = reader.ReadInt32();

            //Metadata
            ushort len = reader.ReadUInt16();
            if (len > 0)
            {
                metadata = reader.ReadBytes(len);
            }

            //ResultItemList
            int listCount = reader.ReadInt32();
            resultItemList = new List<ResultItem>(listCount);
            if (listCount > 0)
            {
                ResultItem resultItem;
                for (int i = 0; i < listCount; i++)
                {
                    resultItem = new ResultItem();
                    resultItem.Deserialize(reader);
                    resultItemList.Add(resultItem);
                }
            }

            //ExceptionInfo
            exceptionInfo = reader.ReadString();

            //VirtualCount
            if (version >= 2)
            {
                virtualCount = reader.ReadInt32();
            }
		}
Пример #4
0
        public override void Deserialize(IPrimitiveReader reader, int version)
        {
            //ResultItemList
            int listCount = reader.ReadInt32();

            ResultItemList = new List <ResultItem>(listCount);
            if (listCount > 0)
            {
                ResultItem resultItem;
                for (int i = 0; i < listCount; i++)
                {
                    resultItem = new ResultItem();
                    resultItem.Deserialize(reader);
                    ResultItemList.Add(resultItem);
                }
            }

            //IndexIdIndexHeaderMapping
            ushort count = reader.ReadUInt16();
            ushort len;

            if (count > 0)
            {
                IndexIdIndexHeaderMapping = new Dictionary <byte[], IndexHeader>(count, new ByteArrayEqualityComparer());
                byte[]      indexId;
                IndexHeader indexHeader;

                for (ushort i = 0; i < count; i++)
                {
                    len     = reader.ReadUInt16();
                    indexId = null;
                    if (len > 0)
                    {
                        indexId = reader.ReadBytes(len);
                    }
                    indexHeader = new IndexHeader();
                    Serializer.Deserialize(reader.BaseStream, indexHeader);

                    IndexIdIndexHeaderMapping.Add(indexId, indexHeader);
                }
            }

            //TotalCount
            TotalCount = reader.ReadInt32();

            //IsTagPrimarySort
            IsTagPrimarySort = reader.ReadBoolean();

            //SortFieldName
            SortFieldName = reader.ReadString();

            //SortOrderList
            count         = reader.ReadUInt16();
            SortOrderList = new List <SortOrder>(count);
            SortOrder sortOrder;

            for (int i = 0; i < count; i++)
            {
                sortOrder = new SortOrder();
                sortOrder.Deserialize(reader);
                SortOrderList.Add(sortOrder);
            }

            //ExceptionInfo
            ExceptionInfo = reader.ReadString();

            //AdditionalAvailableItemCount
            AdditionalAvailableItemCount = reader.ReadInt32();

            //IndexCap
            if (version >= 2)
            {
                IndexCap = reader.ReadInt32();
            }

            if (version >= 3)
            {
                if (reader.ReadBoolean())
                {
                    GroupByResult = new GroupByResult(new BaseComparer(IsTagPrimarySort, SortFieldName, SortOrderList));
                    Serializer.Deserialize(reader.BaseStream, GroupByResult);
                }
            }
        }
Пример #5
0
        public override void Deserialize(IPrimitiveReader reader, int version)
        {
            // set the object's current version to the server's object version
            if (version < CORRECT_SERVERSIDE_PAGING_LOGIC_VERSION)
            {
                this.currentVersion = version;
            }

            //ResultItemList
            int listCount = reader.ReadInt32();

            ResultItemList = new List <ResultItem>(listCount);
            if (listCount > 0)
            {
                ResultItem resultItem;
                for (int i = 0; i < listCount; i++)
                {
                    resultItem = new ResultItem();
                    resultItem.Deserialize(reader);
                    ResultItemList.Add(resultItem);
                }
            }

            //IndexIdIndexHeaderMapping
            ushort count = reader.ReadUInt16();

            if (count > 0)
            {
                IndexIdIndexHeaderMapping = new Dictionary <byte[], IndexHeader>(count, new ByteArrayEqualityComparer());
                byte[]      indexId;
                IndexHeader indexHeader;
                ushort      len;

                for (ushort i = 0; i < count; i++)
                {
                    len     = reader.ReadUInt16();
                    indexId = null;
                    if (len > 0)
                    {
                        indexId = reader.ReadBytes(len);
                    }
                    indexHeader = new IndexHeader();
                    Serializer.Deserialize(reader.BaseStream, indexHeader);

                    IndexIdIndexHeaderMapping.Add(indexId, indexHeader);
                }
            }

            //TotalCount
            TotalCount = reader.ReadInt32();

            //IsTagPrimarySort
            IsTagPrimarySort = reader.ReadBoolean();

            //SortFieldName
            SortFieldName = reader.ReadString();

            //SortOrderList
            count         = reader.ReadUInt16();
            SortOrderList = new List <SortOrder>(count);
            SortOrder sortOrder;

            for (int i = 0; i < count; i++)
            {
                sortOrder = new SortOrder();
                sortOrder.Deserialize(reader);
                SortOrderList.Add(sortOrder);
            }

            //ExceptionInfo
            ExceptionInfo = reader.ReadString();

            if (version >= 2)
            {
                //PageableItemCount
                AdditionalAvailableItemCount = reader.ReadInt32();
            }
        }
Пример #6
0
        public override SpanQueryResult MergeResults(IList <SpanQueryResult> partialResults)
        {
            SpanQueryResult finalResult = default(SpanQueryResult);

            if (partialResults == null || partialResults.Count == 0)
            {
                return(finalResult);
            }

            // We have partialResults to process
            ByteArrayEqualityComparer byteArrayEqualityComparer = new ByteArrayEqualityComparer();
            BaseComparer baseComparer = null;
            Dictionary <byte[] /*IndexId*/, IndexHeader /*IndexHeader*/> completeIndexIdIndexHeaderMapping =
                new Dictionary <byte[], IndexHeader>(byteArrayEqualityComparer);

            if (partialResults.Count == 1)
            {
                #region  Just one cluster was targeted, so no need to merge anything

                finalResult = partialResults[0];

                #endregion
            }
            else
            {
                #region  More than one clusters was targeted

                List <ResultItem> completeResultItemList = new List <ResultItem>();
                GroupByResult     completeGroupByResult  = new GroupByResult(null);
                int           totalCount = 0;
                int           additionalAvailableItemCount = 0;
                StringBuilder exceptionStringBuilder       = new StringBuilder();
                bool          indexCapSet = false;
                int           indexCap    = 0;

                foreach (SpanQueryResult partialResult in partialResults)
                {
                    if (partialResult != null)
                    {
                        #region Compute TotalCount

                        totalCount += partialResult.TotalCount;

                        #endregion

                        #region Assign IndexCap

                        if (!indexCapSet)
                        {
                            indexCap    = partialResult.IndexCap;
                            indexCapSet = true;
                        }

                        #endregion

                        #region Compute PageableItemCount

                        if (GetAdditionalAvailableItemCount)
                        {
                            additionalAvailableItemCount += partialResult.AdditionalAvailableItemCount;
                        }

                        #endregion

                        #region Merge Results

                        if ((partialResult.ResultItemList != null && partialResult.ResultItemList.Count > 0) ||
                            (partialResult.GroupByResult != null && partialResult.GroupByResult.Count > 0))
                        {
                            if (baseComparer == null)
                            {
                                baseComparer = new BaseComparer(partialResult.IsTagPrimarySort,
                                                                partialResult.SortFieldName,
                                                                partialResult.SortOrderList);
                                completeGroupByResult = new GroupByResult(baseComparer);
                            }

                            if (GroupBy == null)
                            {
                                MergeAlgo.MergeItemLists(ref completeResultItemList,
                                                         partialResult.ResultItemList,
                                                         MaxMergeCount,
                                                         baseComparer);
                            }
                            else
                            {
                                MergeAlgo.MergeGroupResult(ref completeGroupByResult,
                                                           partialResult.GroupByResult,
                                                           MaxMergeCount,
                                                           baseComparer);
                            }
                        }

                        #endregion

                        #region Update IndexIdIndexHeaderMapping

                        if (GetIndexHeaderType != GetIndexHeaderType.None &&
                            partialResult.IndexIdIndexHeaderMapping != null &&
                            partialResult.IndexIdIndexHeaderMapping.Count > 0)
                        {
                            foreach (KeyValuePair <byte[], IndexHeader> kvp in partialResult.IndexIdIndexHeaderMapping)
                            {
                                if (!completeIndexIdIndexHeaderMapping.ContainsKey(kvp.Key))
                                {
                                    completeIndexIdIndexHeaderMapping.Add(kvp.Key, kvp.Value);
                                }
                            }
                        }

                        #endregion

                        #region Update exceptionInfo

                        if (!String.IsNullOrEmpty(partialResult.ExceptionInfo))
                        {
                            exceptionStringBuilder.Append(partialResult.ExceptionInfo);
                            exceptionStringBuilder.Append(" ");
                        }

                        #endregion
                    }
                }

                #region Create FinalResult

                finalResult = new SpanQueryResult
                {
                    ResultItemList = completeResultItemList,
                    GroupByResult  = completeGroupByResult,
                    TotalCount     = totalCount,
                    AdditionalAvailableItemCount = additionalAvailableItemCount,
                    IndexCap = indexCap
                };

                //Assign sort fields for use in GroupBy remote queries
                if (baseComparer != null)
                {
                    finalResult.IsTagPrimarySort = baseComparer.IsTagPrimarySort;
                    finalResult.SortFieldName    = baseComparer.SortFieldName;
                    finalResult.SortOrderList    = baseComparer.SortOrderList;
                }

                if (GetIndexHeaderType != GetIndexHeaderType.None && completeIndexIdIndexHeaderMapping.Count > 0)
                {
                    finalResult.IndexIdIndexHeaderMapping = completeIndexIdIndexHeaderMapping;
                }

                if (exceptionStringBuilder.Length > 0)
                {
                    finalResult.ExceptionInfo = exceptionStringBuilder.ToString();
                }

                #endregion

                #endregion
            }

            #region Spanning and Update IndexIdIndexHeaderMapping if required

            if (ClientSideSubsetProcessingRequired && Span != 0 && finalResult != null)
            {
                #region Spanning

                if (GroupBy == null)
                {
                    List <ResultItem> filteredResultItemList = new List <ResultItem>();
                    if (finalResult.ResultItemList.Count >= Offset)
                    {
                        for (int i = Offset - 1; i < finalResult.ResultItemList.Count && filteredResultItemList.Count < Span; i++)
                        {
                            filteredResultItemList.Add(finalResult.ResultItemList[i]);
                        }
                    }
                    finalResult.ResultItemList = filteredResultItemList;
                }
                else if (finalResult.GroupByResult != null && finalResult.GroupByResult.Count > 0)
                {
                    GroupByResult filteredGroupByResult = new GroupByResult(baseComparer);
                    if (finalResult.GroupByResult.Count >= Offset)
                    {
                        for (int i = Offset - 1; i < finalResult.GroupByResult.Count && filteredGroupByResult.Count < Span; i++)
                        {
                            filteredGroupByResult.Add(finalResult.GroupByResult[i].CompositeKey, finalResult.GroupByResult[i]);
                        }
                    }
                    finalResult.GroupByResult = filteredGroupByResult;
                }

                #endregion

                #region Update IndexIdIndexHeaderMapping to only include metadata relevant after paging

                if (partialResults.Count != 1 && GetIndexHeaderType == GetIndexHeaderType.ResultItemsIndexIds && completeIndexIdIndexHeaderMapping.Count > 0)
                {
                    Dictionary <byte[] /*IndexId*/, IndexHeader /*IndexHeader*/> filteredIndexIdIndexHeaderMapping = new Dictionary <byte[], IndexHeader>(byteArrayEqualityComparer);
                    if (GroupBy == null)
                    {
                        foreach (ResultItem resultItem in finalResult.ResultItemList)
                        {
                            if (!filteredIndexIdIndexHeaderMapping.ContainsKey(resultItem.IndexId))
                            {
                                filteredIndexIdIndexHeaderMapping.Add(resultItem.IndexId, completeIndexIdIndexHeaderMapping[resultItem.IndexId]);
                            }
                        }
                    }
                    else if (finalResult.GroupByResult != null && finalResult.GroupByResult.Count > 0)
                    {
                        foreach (ResultItemBag resultItemBag in finalResult.GroupByResult)
                        {
                            for (int i = 0; i < resultItemBag.Count; i++)
                            {
                                ResultItem resultItem = resultItemBag[i];
                                if (!filteredIndexIdIndexHeaderMapping.ContainsKey(resultItem.IndexId))
                                {
                                    filteredIndexIdIndexHeaderMapping.Add(resultItem.IndexId, completeIndexIdIndexHeaderMapping[resultItem.IndexId]);
                                }
                            }
                        }
                    }
                    finalResult.IndexIdIndexHeaderMapping = filteredIndexIdIndexHeaderMapping.Count > 0 ? filteredIndexIdIndexHeaderMapping : null;
                }

                #endregion
            }

            #endregion
            return(finalResult);
        }
Пример #7
0
 public void Add(ResultItem resultItem)
 {
     ItemBag.Add(resultItem);
 }
Пример #8
0
        public void Deserialize(IPrimitiveReader reader, int version)
        {
            //IndexExists
            IndexExists = reader.ReadBoolean();

            //IndexSize
            IndexSize = reader.ReadInt32();

            //Metadata
            ushort len = reader.ReadUInt16();

            if (len > 0)
            {
                Metadata = reader.ReadBytes(len);
            }

            //FirstPageResultItemList
            int listCount = reader.ReadInt32();

            FirstPageResultItemList = new List <ResultItem>(listCount);
            if (listCount > 0)
            {
                ResultItem resultItem;
                for (int i = 0; i < listCount; i++)
                {
                    resultItem = new ResultItem();
                    resultItem.Deserialize(reader);
                    FirstPageResultItemList.Add(resultItem);
                }
            }

            //LastPageResultItemList
            listCount = reader.ReadInt32();
            LastPageResultItemList = new List <ResultItem>(listCount);
            if (listCount > 0)
            {
                ResultItem resultItem;
                for (int i = 0; i < listCount; i++)
                {
                    resultItem = new ResultItem();
                    resultItem.Deserialize(reader);
                    LastPageResultItemList.Add(resultItem);
                }
            }

            //ExceptionInfo
            ExceptionInfo = reader.ReadString();

            //VirtualCount
            if (version >= 2)
            {
                VirtualCount = reader.ReadInt32();
            }

            //IndexCap
            if (version >= 3)
            {
                IndexCap = reader.ReadInt32();
            }

            if (version >= 4)
            {
                //MetadataPropertyCollection
                if (reader.ReadBoolean())
                {
                    MetadataPropertyCollection = new MetadataPropertyCollection();
                    Serializer.Deserialize(reader.BaseStream, MetadataPropertyCollection);
                }
            }
        }