/// <summary> /// Maps data from a stream into a new form. /// </summary> public static IStream <TTo, TCursor> Map <TFrom, TTo, TCursor>( this IStream <TFrom, TCursor> source, Func <IEnumerable <TFrom>, IEnumerable <TTo> > map, string id = null) { return(Create <TTo, TCursor>( id: id ?? string.Format("{0}->Map(d:{1})", source.Id, typeof(TTo).ReadableName()), query: async q => { var query = source.CreateQuery(q.Cursor, q.BatchSize); var sourceBatch = await source.Fetch(query); var mappedItems = map(sourceBatch); var mappedCursor = Cursor.New <TCursor>(sourceBatch.StartsAtCursorPosition); var mappedBatch = StreamBatch.Create(mappedItems, mappedCursor); return mappedBatch; }, advanceCursor: (query, batch) => { // don't advance the cursor in the map operation, since sourceStream.Fetch will already have done it }, newCursor: source.NewCursor)); }
private static IStream <TData, TCursor> Create <TData, TCursor>( Func <IStreamQuery <TCursor>, IEnumerable <TData> > query, string id = null, Action <IStreamQuery <TCursor>, IStreamBatch <TData> > advanceCursor = null, Func <ICursor <TCursor> > newCursor = null, IEnumerable <TData> source = null) { return(new AnonymousStream <TData, TCursor>( id, async q => StreamBatch.Create(query(q), q.Cursor), advanceCursor, newCursor, source)); }
/// <summary> /// Creates a partitioned stream. /// </summary> /// <typeparam name="TData">The type of the data.</typeparam> /// <typeparam name="TCursor">The type of the cursor.</typeparam> /// <typeparam name="TPartition">The type of the partition.</typeparam> /// <param name="query">The query.</param> /// <param name="id">The base identifier for the partitioned stream.</param> /// <param name="advanceCursor">A delegate that advances the cursor after a batch is pulled from the stream.</param> /// <param name="newCursor">A delegate that returns a new cursor.</param> public static IPartitionedStream <TData, TCursor, TPartition> PartitionedByValue <TData, TCursor, TPartition>( Func <IStreamQuery <TCursor>, IStreamQueryValuePartition <TPartition>, Task <IEnumerable <TData> > > query, string id = null, Action <IStreamQuery <TCursor>, IStreamBatch <TData> > advanceCursor = null, Func <ICursor <TCursor> > newCursor = null) { return(new AnonymousPartitionedStream <TData, TCursor, TPartition>( id: id, fetch: async(q, partition) => { q.BatchSize = q.BatchSize ?? StreamBatch.MaxSize; var batch = await query(q, (IStreamQueryValuePartition <TPartition>)partition); return StreamBatch.Create(batch, q.Cursor); }, advanceCursor: advanceCursor, newCursor: newCursor)); }
/// <summary> /// Creates a stream based on a queryable data source. /// </summary> /// <typeparam name="TData">The type of the stream's data.</typeparam> /// <typeparam name="TCursor">The type of the cursor.</typeparam> /// <param name="id">The stream identifier.</param> /// <param name="query">The query.</param> /// <param name="advanceCursor">A delegate that advances the cursor after a batch is pulled from the stream.</param> /// <param name="newCursor">A delegate that returns a new cursor.</param> /// <returns></returns> public static IStream <TData, TCursor> Create <TData, TCursor>( string id, Func <IStreamQuery <TCursor>, Task <IEnumerable <TData> > > query, Action <IStreamQuery <TCursor>, IStreamBatch <TData> > advanceCursor = null, Func <ICursor <TCursor> > newCursor = null) { return(new AnonymousStream <TData, TCursor>( id, async q => { var cursor = q.Cursor.Clone(); var data = await query(q); return data as IStreamBatch <TData> ?? StreamBatch.Create(data, cursor); }, advanceCursor, newCursor)); }