func WalkViewInBatches(result chan cb.ViewRow, errs query.ErrorChannel, bucket *cb.Bucket, ddoc string, view string, options map[string]interface{}, batchSize int64, limit int64) { if limit != 0 && limit < batchSize { batchSize = limit } defer close(result) defer close(errs) defer func() { r := recover() if r != nil { clog.Error(fmt.Errorf("View Walking Panic: %v\n%s", r, debug.Stack())) errs <- query.NewError(nil, "Panic In View Walking") } }() options["limit"] = batchSize + 1 numRead := int64(0) ok := true for ok { logURL, err := bucket.ViewURL(ddoc, view, options) if err == nil { clog.To(NETWORK_CHANNEL, "Request View: %v", logURL) } vres, err := bucket.View(ddoc, view, options) if err != nil { errs <- query.NewError(err, "Unable to access view") return } for i, row := range vres.Rows { if int64(i) < batchSize { // dont process the last row, its just used to see if we // need to continue processing result <- row numRead += 1 } } if (int64(len(vres.Rows)) > batchSize) && (limit == 0 || (limit != 0 && numRead < limit)) { // prepare for next run skey := vres.Rows[batchSize].Key skeydocid := vres.Rows[batchSize].ID options["startkey"] = skey options["startkey_docid"] = cb.DocId(skeydocid) } else { // stop ok = false } } }
// Iterate the list of blobs registered to this node and emit them // into the given channel. func (n StorageNode) iterateBlobs(ch chan<- string, cherr chan<- error, quit <-chan bool) { defer close(ch) if cherr != nil { defer close(cherr) } viewRes := struct { Rows []struct { Id string } Errors []cb.ViewError }{} startDocId := "" done := false limit := 1000 for !done { params := map[string]interface{}{ "key": n.name, "reduce": false, "limit": limit, } if startDocId != "" { params["startkey_docid"] = cb.DocId(startDocId) } err := couchbase.ViewCustom("cbfs", "node_blobs", params, &viewRes) if err != nil { cherr <- err return } for _, e := range viewRes.Errors { cherr <- e } done = len(viewRes.Rows) < limit for _, r := range viewRes.Rows { startDocId = r.Id select { case <-quit: return case ch <- startDocId[1:]: // We sent one. } } } }
"github.com/couchbaselabs/dparval" cb "github.com/couchbaselabs/go-couchbase" "github.com/couchbaselabs/tuqtng/catalog" "github.com/couchbaselabs/tuqtng/query" ) const NETWORK_CHANNEL = "NETWORK" const TYPE_NULL = 64 const TYPE_BOOLEAN = 96 const TYPE_NUMBER = 128 const TYPE_STRING = 160 const TYPE_ARRAY = 192 const TYPE_OBJECT = 224 var MIN_ID = cb.DocId("") var MAX_ID = cb.DocId(strings.Repeat(string([]byte{0xff}), 251)) func ViewTotalRows(bucket *cb.Bucket, ddoc string, view string, options map[string]interface{}) (int64, query.Error) { options["limit"] = 0 logURL, err := bucket.ViewURL(ddoc, view, options) if err == nil { clog.To(NETWORK_CHANNEL, "Request View: %v", logURL) } vres, err := bucket.View(ddoc, view, options) if err != nil { return 0, query.NewError(err, "Unable to access view") } return int64(vres.TotalRows), nil