func request_get_VRANGE(q *btrdb.Quasar, w http.ResponseWriter, r *http.Request) { atomic.AddInt32(&outstandingHttpReqs, 1) defer func() { atomic.AddInt32(&outstandingHttpReqs, -1) }() r.ParseForm() ids := r.Form.Get(":uuid") id := uuid.Parse(ids) if id == nil { log.Critical("ids: '%v'", ids) doError(w, "malformed uuid") return } st, ok, msg := parseInt(r.Form.Get("starttime"), -(16 << 56), (48 << 56)) if !ok { doError(w, "bad start time: "+msg) return } et, ok, msg := parseInt(r.Form.Get("endtime"), -(16 << 56), (48 << 56)) if !ok { doError(w, "bad end time: "+msg) return } if et <= st { doError(w, "end time <= start time") return } versions := r.Form.Get("ver") if versions == "" { versions = "0" } //Technically this is incorrect, but I doubt we will overflow this versioni, ok, msg := parseInt(versions, 0, 1<<63-1) version := uint64(versioni) if !ok { doError(w, "malformed version: "+msg) return } if version == 0 { version = btrdb.LatestGeneration } unitoftime := r.Form.Get("unitoftime") uot := struct { UnitofTime string }{unitoftime} divisor := int64(1) switch unitoftime { case "": fallthrough case "ms": divisor = 1000000 //ns to ms case "ns": divisor = 1 case "us": divisor = 1000 //ns to us case "s": divisor = 1000000000 //ns to s default: doError(w, "unitoftime must be 'ns', 'ms', 'us' or 's'") return } if st >= btrdb.MaximumTime/divisor || st <= btrdb.MinimumTime/divisor { doError(w, "start time out of bounds") return } if et >= btrdb.MaximumTime/divisor || et <= btrdb.MinimumTime/divisor { doError(w, "end time out of bounds") return } st *= divisor et *= divisor pws := r.Form.Get("pw") pw := uint8(0) if pws != "" { pwl, ok, msg := parseInt(pws, 0, 63) if !ok { doError(w, "bad point width: "+msg) return } if divisor != 1 { doError(w, "statistical results require unitoftime=ns") return } pw = uint8(pwl) } if pws != "" { //log.Info("HTTP REQ id=%s pw=%v", id.String(), pw) logh("QSV", fmt.Sprintf("st=%v et=%v pw=%v u=%s", st, et, pw, id.String()), r) res, rgen, err := q.QueryStatisticalValues(id, st, et, version, pw) if err != nil { doError(w, "query error: "+err.Error()) return } resf := make([][]interface{}, len(res)) contents := make([]interface{}, len(res)*6) for i := 0; i < len(res); i++ { resf[i] = contents[i*6 : (i+1)*6] resf[i][0] = res[i].Time / 1000000 //ms since epoch resf[i][1] = res[i].Time % 1000000 //nanoseconds left over resf[i][2] = res[i].Min resf[i][3] = res[i].Mean resf[i][4] = res[i].Max resf[i][5] = res[i].Count } rv := []struct { Uuid string `json:"uuid"` XReadings [][]interface{} Version uint64 `json:"version"` }{ {id.String(), resf, rgen}, } err = json.NewEncoder(w).Encode(rv) if err != nil { doError(w, "JSON error: "+err.Error()) return } return } else { logh("QV", fmt.Sprintf("st=%v et=%v pw=%v u=%s", st, et, pw, id.String()), r) res, rgen, err := q.QueryValues(id, st, et, version) if err != nil { doError(w, "query error: "+err.Error()) return } resf := make([][]interface{}, len(res)) contents := make([]interface{}, len(res)*2) for i := 0; i < len(res); i++ { resf[i] = contents[i*2 : (i+1)*2] resf[i][0] = res[i].Time / divisor resf[i][1] = res[i].Val } //props := struct{Uot string `json:"UnitofTime"`}{"foo"} rv := []struct { Uuid string `json:"uuid"` Readings [][]interface{} Version uint64 `json:"version"` Properties interface{} `json:"Properties"` }{ {id.String(), resf, rgen, uot}, } err = json.NewEncoder(w).Encode(rv) if err != nil { doError(w, "JSON error: "+err.Error()) return } return } //res, err := q. }