/// <summary> /// Creates and returns set by deserialization /// </summary> /// <param name="reader">general reader</param> /// <param name="itemReader">item reader</param> /// <param name="concurrencyLevel">the concurrency level (all values less than 1024 will be assumed to be 1024)</param> public static ConcurrentBigSet <TItem> Deserialize( BinaryReader reader, Func <TItem> itemReader, int concurrencyLevel = DefaultConcurrencyLevel) { var count = reader.ReadInt32(); var nodeLength = reader.ReadInt32(); var itemsPerBufferBitWidth = reader.ReadInt32(); var capacity = Math.Max(MinConcurrencyLevel, Math.Max(nodeLength, concurrencyLevel)); var items = new BigBuffer <TItem>(itemsPerBufferBitWidth); items.Initialize(capacity); var nodes = new BigBuffer <Node>(NodesPerEntryBufferBitWidth); nodes.Initialize(capacity); var itemsAccessor = items.GetAccessor(); var nodesAccessor = nodes.GetAccessor(); List <int> freeNodes = new List <int>(); for (int i = 0; i < nodeLength; i++) { var hashCode = reader.ReadInt32(); if (hashCode != Node.UnusedHashCode) { var next = reader.ReadInt32(); var item = itemReader(); nodesAccessor[i] = new Node(hashCode, next); itemsAccessor[i] = item; } else { freeNodes.Add(i); } } var buckets = Buckets.Deserialize(reader); var result = new ConcurrentBigSet <TItem>( concurrencyLevel, items, nodes, buckets, nodeLength); result.m_count = count; // distribute free nodes var accessors = result.m_accessors; foreach (var i in freeNodes) { var lockNo = result.GetLockNo(i); result.AddFreeNode(lockNo, i, ref accessors); } return(result); }