func mergeDomains(engine storage.Engine, w origins.Writer, domains []string, since, asof time.Time) int { var ( err error count int log *view.Log ) iters := make([]origins.Iterator, len(domains)) // Merge and output facts across domains. for i, d := range domains { log, err = view.OpenLog(engine, d, "commit") if err != nil { logrus.Fatal(err) } iters[i] = log.View(since, asof) } if count, err = origins.Copy(view.Merge(iters...), w); err != nil { logrus.Fatal(err) } return count }
func TestMultiDomainLogIter(t *testing.T) { domains := []string{"test", "another_test"} // Number of transactions n := 100 // Number of facts per transaction m := 100 engine := randMultidomainStorage(domains, n, m) // Open and merge the commit logs. log0, err := view.OpenLog(engine, domains[0], "commit") if err != nil { t.Fatal(err) } log1, err := view.OpenLog(engine, domains[1], "commit") if err != nil { t.Fatal(err) } now := time.Now() mergedStreams := view.Merge(log0.Asof(now), log1.Asof(now)) if err = mergedStreams.Err(); err != nil { t.Fatal(err) } i := 0 var prevTrnId uint64 = 1<<64 - 1 for { f := mergedStreams.Next() if err = mergedStreams.Err(); err != nil { t.Fatal(err) } if f == nil { break } else { if prevTrnId < f.Transaction { t.Errorf("Transactions are ordered incorrectly") } i++ } } if i != n*m { t.Errorf("expected %d facts, got %d", n*m, i) } }
func benchmarkDomainMerge(b *testing.B, numTrn, factsPerTrn, numDomains int) { var err error domains := make([]string, numDomains) iters := make([]origins.Iterator, len(domains)) logs := make([]*view.Log, len(domains)) for j := 0; j < numDomains; j++ { domains[j] = "domain_" + strconv.Itoa(j+1) } engine := randMultidomainStorage(domains, numTrn, factsPerTrn) for j := 0; j < len(domains); j++ { logs[j], err = view.OpenLog(engine, domains[j], "commit") if err != nil { b.Fatal(err) } } now := time.Now() b.ResetTimer() for i := 0; i < b.N; i++ { for j := 0; j < len(domains); j++ { iters[j] = logs[j].Asof(now) } iter := view.Merge(iters...) if err := iter.Err(); err != nil { b.Fatal(err) } // The Merge() operation is lazy, and most of the actual work happens during Next(), // so to evaluate the true cost of merging we need to time how long it takes to step // through the resulting iterator. _, err = testNext(iter) if err != nil { b.Fatal(err) } } }