Пример #1
0
// Consume fetches the values. s is a Stream of T.
func (pb *PageBuffer) Consume(s functional.Stream) (err error) {
	pb.page_no = 0
	pb.idx = 0
	pb.is_end = false
	for err == nil && !pb.isDesiredPageRead() {
		if pb.idx > 0 {
			pb.page_no++
		}
		offset := pb.pageOffset(pb.page_no)
		pb.idx, err = readStreamIntoSlice(
			s, pb.buffer.Slice(offset, offset+pb.pageLen), pb.handler)
	}
	if err == nil {
		anElement := pb.buffer.Index(pb.pageOffset(pb.page_no + 1))
		pb.handler.ensureValid(anElement)
		pb.is_end = s.Next(pb.handler.toInterface(anElement)) == functional.Done
	} else if err == functional.Done {
		pb.is_end = true
		err = nil
		if pb.page_no > 0 && pb.idx == 0 {
			pb.page_no--
			pb.idx = pb.pageLen
		}
	}
	return
}
Пример #2
0
// FirstOnly reads the first value from stream storing it in ptr.
// FirstOnly returns emptyError if no values were on stream.
func FirstOnly(stream functional.Stream, emptyError error, ptr interface{}) (err error) {
	err = stream.Next(ptr)
	if err == functional.Done {
		err = emptyError
		return
	}
	return
}
Пример #3
0
func verifyTimes(t *testing.T, s functional.Stream, expectedTimes ...time.Time) {
	var actual time.Time
	for _, expected := range expectedTimes {
		if s.Next(&actual) != nil {
			t.Error("Stream too short.")
			return
		}
		if actual != expected {
			t.Errorf("Expected %v, got %v", expected, actual)
		}
	}
	if s.Next(&actual) != functional.Done {
		t.Error("Stream too long.")
	}
}
Пример #4
0
func readStreamIntoSlice(
	s functional.Stream,
	aSlice reflect.Value,
	handler elementHandler) (numRead int, err error) {
	l := aSlice.Len()
	for numRead = 0; numRead < l; numRead++ {
		anElement := aSlice.Index(numRead)
		handler.ensureValid(anElement)
		err = s.Next(handler.toInterface(anElement))
		if err != nil {
			break
		}
	}
	return
}
// ByYear takes a Stream of DateCount instances and returns a Stream of
// YearCount instances by totaling the counts in the DateCount instances
// by year. The DateCount instances must be ordered by Date. Caller must Close
// the returned Stream. Calling Close on returned Stream also closes s.
func ByYear(s functional.Stream) functional.Stream {
	return functional.NewGenerator(func(e functional.Emitter) error {
		var ptr interface{}
		var opened bool
		var incoming DateCount

		// As soon as caller calls Close() we quit without pulling unnecessary
		// values from underlying stream.
		if ptr, opened = e.EmitPtr(); !opened {
			return s.Close()
		}
		var err error

		// We get the first date while propagating any errors to the caller.
		// Note that we stay in this loop until either we get a first date or
		// caller calls Close()
		for err = s.Next(&incoming); err != nil; err = s.Next(&incoming) {
			// Propagate error and yield execution to caller. Then get the next
			// pointer caller pases to Next().
			if ptr, opened = e.Return(err); !opened {
				return s.Close()
			}
		}
		currentYear := incoming.Date.Year()

		// Running total for current year
		sum := incoming.Count

		// When Done marker is reached, we have to emit the count of the final year.
		for err = s.Next(&incoming); err != functional.Done; err = s.Next(&incoming) {

			// Propagate any errors to caller.
			if err != nil {
				if ptr, opened = e.Return(err); !opened {
					return s.Close()
				}
				continue
			}
			year := incoming.Date.Year()

			// If year changed, emit the count for the current year.
			// Then change currentYear and and make sum be the running total for
			// that year.
			if year != currentYear {
				*ptr.(*YearCount) = YearCount{Year: currentYear, Count: sum}
				if ptr, opened = e.Return(nil); !opened {
					return s.Close()
				}
				sum = incoming.Count
				currentYear = year
			} else {
				sum += incoming.Count
			}
		}
		// Emit the final year.
		*ptr.(*YearCount) = YearCount{Year: currentYear, Count: sum}

		// Note that we return nil, not functional.Done, since we are emitting the
		// count for the final year. The call to WaitForClose() takes
		// care of returning functional.Done to the caller until the caller calls
		// Close()
		e.Return(nil)
		functional.WaitForClose(e)
		return s.Close()
	})
}