/// <summary> /// <para>Initializes a new instance of the <see cref="ObjectListForSingles{T, THeader}"/> class /// for an existing list.</para> /// </summary> /// <param name="storage"> /// <para>The <see cref="SerializingObjectStorage"/> containing the list.</para> /// </param> /// <param name="keySpace"> /// <para>The <see cref="DataBuffer"/> keyspace the list is stored in.</para> /// </param> /// <param name="key"> /// <para>The single <see cref="StorageKey"/> all the binary entries are /// stored under.</para> /// </param> /// <param name="buffer"> /// <para><see cref="DataBuffer"/> that holds the entire list. If /// <see cref="DataBuffer.IsEmpty"/> is true, then the list is read /// from <paramref name="storage"/>.</para> /// </param> /// <param name="creator"> /// <para>The <see cref="Func{T}"/> that produces new <typeparamref name="T"/> /// instances for deserialization.</para> /// </param> /// <param name="headerCreator"> /// <para>The <see cref="Func{THeader}"/> that produces new <typeparamref name="THeader"/> /// instances for deserialization.</para> /// </param> public ObjectListForSingles(SerializingObjectStorage storage, DataBuffer keySpace, StorageKey key, DataBuffer buffer, Func <T> creator, Func <THeader> headerCreator) : this(storage, keySpace, key, creator) { ArraySegment <byte> seg; if (buffer.IsEmpty) { _stream = _pooled.Item; buffer = SerializingObjectStorage.GetReadBuffer(_stream); var entryLen = storage.Storage.Get(keySpace, key, buffer); if (entryLen < 0) { throw new ApplicationException(string.Format( "No list found for key space '{0}', key '{1}'", keySpace, key)); } var bfExcess = SerializingObjectStorage.GetExcessBuffer(_stream, buffer, entryLen); if (bfExcess.IsEmpty) { buffer = buffer.Restrict(entryLen); } else { if (storage.Storage.SupportsIncompleteReads) { storage.Storage.Get(keySpace, key, buffer.Length, bfExcess.RestrictOffset(buffer.Length)); } else { storage.Storage.Get(keySpace, key, 0, bfExcess); } buffer = bfExcess; } seg = buffer.ByteArraySegmentValue; } else { _pooled.Dispose(); _pooled = null; seg = buffer.ByteArraySegmentValue; _stream = new MemoryStream(seg.Array, seg.Offset, seg.Count); } var ticks = BitConverter.ToInt64(seg.Array, seg.Offset); // expires listed first, since SetExpires can change it by itself // and this way it doesn't have to worry about future changes // to header Expires = new DateTime(ticks); _stream.Position = sizeof(long); _header = headerCreator(); Serializer.Deserialize(_stream, _header); _headerLength = _stream.Position; }
/// <summary> /// <para>Returns an enumerator that iterates through the collection.</para> /// </summary> /// <returns> /// <para>A <see cref="IEnumerator{T}"/> that can be used to iterate through the collection.</para> /// </returns> public IEnumerator <T> GetEnumerator() { _stream.Position = _headerLength; while (_stream.Position < _stream.Length) { var instance = Creator(); Serializer.Deserialize(_stream, instance); yield return(instance); } }
/// <summary> /// <para>Advances the enumerator to the next element of the collection.</para> /// </summary> /// <returns> /// <para>true if the enumerator was successfully advanced to the next element; false if the enumerator has passed the end of the collection.</para> /// </returns> /// <exception cref="System.InvalidOperationException"> /// <para>The collection was modified after the enumerator was created.</para> /// </exception> public bool MoveNext() { //if (!_list.Cursor.MoveNext()) return false; using (var itemValue = _list.Storage.StreamPool.GetItem()) { DataBuffer valueBuffer; var results = _list.ReadCursor(itemValue, out valueBuffer); if (results < 0) { return(false); } var stream = itemValue.Item; stream.Position = 0; _current = _list.Creator(); Serializer.Deserialize(stream, _current); return(true); } }
/// <summary> /// <para>Initializes a new instance of the <see cref="ObjectListForMultiples{T, THeader}"/> class /// for an existing list.</para> /// </summary> /// <param name="storage"> /// <para>The <see cref="SerializingObjectStorage"/> containing the list.</para> /// </param> /// <param name="keySpace"> /// <para>The <see cref="DataBuffer"/> keyspace the list is stored in.</para> /// </param> /// <param name="key"> /// <para>The single <see cref="StorageKey"/> all the binary entries are /// stored under.</para> /// </param> /// <param name="creator"> /// <para>The <see cref="Func{T}"/> that produces new <typeparamref name="T"/> /// instances for deserialization.</para> /// </param> /// <param name="headerCreator"> /// <para>The <see cref="Func{THeader}"/> that produces new <typeparamref name="THeader"/> /// instances for deserialization.</para> /// </param> public ObjectListForMultiples(SerializingObjectStorage storage, DataBuffer keySpace, StorageKey key, Func <T> creator, Func <THeader> headerCreator) : this(storage, keySpace, key, creator, (inst, itemValue) => { inst.SetCursor(); DataBuffer valueBuffer; if (inst.ReadCursor(itemValue, out valueBuffer) < 0) { throw new ApplicationException(string.Format( "No list for multiples header found for key space '{0}', key '{1}'", keySpace, key)); } var seg = valueBuffer.ByteArraySegmentValue; var ticks = BitConverter.ToInt64(seg.Array, seg.Offset); inst.Expires = new DateTime(ticks); var stream = itemValue.Item; stream.Position = sizeof(long); inst._header = headerCreator(); Serializer.Deserialize(stream, inst._header); }) { }
private StorageEntry <T> GetCore <T>(DataBuffer buffer, MemoryStream stream, T instance) { var seg = buffer.ByteArraySegmentValue; if (stream == null) { stream = new MemoryStream(seg.Array, seg.Offset, seg.Count); } var ticks = BitConverter.ToInt64(seg.Array, seg.Offset); // expires listed first, since SetExpires can change it by itself // and this way it doesn't have to worry about future changes // to header var expires = new DateTime(ticks); ticks = BitConverter.ToInt64(seg.Array, seg.Offset + sizeof(long)); var updated = new DateTime(ticks); stream.Position = _headerLength; Serializer.Deserialize(stream, instance); return(new StorageEntry <T>(instance, updated, expires)); }