From 79c122ebaaada74a9fd86442ff53d2a37bfe9b7e Mon Sep 17 00:00:00 2001 From: Florian Forster Date: Thu, 2 Jun 2011 09:52:32 +0200 Subject: [PATCH] Initial commit. --- compact.go | 161 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 161 insertions(+) create mode 100644 compact.go diff --git a/compact.go b/compact.go new file mode 100644 index 0000000..0698f68 --- /dev/null +++ b/compact.go @@ -0,0 +1,161 @@ +package main + +import ( + "fmt" + "os" +) + +type OTS_DataPoint struct { + TimeStamp float64 + Rate float64 +} + +type OTS_Data struct { + TSData []OTS_DataPoint +} + +/* Functions for the sort interface. */ +func (obj *OTS_Data) Len () int { + return (len (obj.TSData)) +} + +func (obj *OTS_Data) Less (i, j int) bool { + if obj.TSData[i].TimeStamp < obj.TSData[j].TimeStamp { + return true + } + return false +} + +func (obj *OTS_Data) Swap (i, j int) { + tmp := obj.TSData[i] + obj.TSData[i] = obj.TSData[j] + obj.TSData[j] = tmp +} + +func Fmod64 (a float64, b float64) float64 { + tmp := int (a / b) + return b * float64 (tmp) +} + +func (obj *OTS_Data) Write (name string) os.Error { + fd, err := os.OpenFile(name, os.O_WRONLY, 0666) + if err != nil { + return err + } + + for i := 0; i < len (obj.TSData); i++ { + data_point := obj.TSData[i] + str := fmt.Sprintf ("%.3f,%g\n", data_point.TimeStamp, data_point.Rate) + + fd.WriteString (str) + } + + fd.Close () + return nil +} + +func ReadFile (name string) (obj *OTS_Data, err os.Error) { +} + +func (raw_data *OTS_Data) Consolidate (interval float64) *OTS_Data { + if interval <= 0.0 { + return nil + } + + ts_raw_first := raw_data.TSData[0].TimeStamp + ts_raw_last := ts_raw_first + + /* Determine the first and last data point. + * XXX: In the future, this should be a sorted list! */ + for i := 1; i < len (raw_data.TSData); i++ { + data_point := raw_data.TSData[i] + + if ts_raw_first > data_point.TimeStamp { + ts_raw_first = data_point.TimeStamp + } + + if ts_raw_last < data_point.TimeStamp { + ts_raw_last = data_point.TimeStamp + } + } + + fmt.Printf ("ts_raw_first = %g; ts_raw_last = %g;\n", + ts_raw_first, ts_raw_last) + + /* Determine the timespan the consolidated data will span. */ + ts_csl_first := Fmod64 (ts_raw_first, interval) + ts_csl_last := Fmod64 (ts_raw_last, interval) + if ts_csl_last < ts_raw_last { + ts_csl_last += interval + } + + fmt.Printf ("ts_csl_first = %g; ts_csl_last = %g;\n", + ts_csl_first, ts_csl_last) + + intervals_num := int ((ts_csl_last - ts_csl_first) / interval) + fmt.Printf ("Got a %gs timespan (%d intervals).\n", + ts_csl_last - ts_csl_first, intervals_num) + + /* Allocate return structure */ + ret_data := new (OTS_Data) + ret_data.TSData = make ([]OTS_DataPoint, intervals_num) + + /* FIXME: This is currently a O(n^2) algorithm. It should instead be a O(n) + * algorithm. This is possible if raw_data is sorted (which, obviously, is a + * O(n log(n)) task). */ + for i := 0; i < intervals_num; i++ { + ts := ts_csl_first + (float64 (i) * interval) + sum := 0.0 + num := 0.0 + + fmt.Printf ("Building data for interval %g.\n", ts) + + ret_data.TSData[i].TimeStamp = ts + + for j := 0; j < len (raw_data.TSData); j++ { + data_point := raw_data.TSData[j] + + if ((data_point.TimeStamp < ts) || (data_point.TimeStamp >= (ts + interval))) { + continue + } + + sum += data_point.Rate + num += 1.0 + } + + /* TODO: Be more clever about how this consolidated rate is computed. */ + if num > 0.0 { + ret_data.TSData[i].Rate = sum / num + } + } + + return ret_data +} + +func (obj *OTS_Data) Print () { + for i := 0; i < len (obj.TSData); i++ { + data_point := obj.TSData[i] + fmt.Printf ("[%g] %g\n", data_point.TimeStamp, data_point.Rate) + } +} /* Print () */ + +func main () { + var data_points []OTS_DataPoint + var raw_data *OTS_Data + var new_data *OTS_Data + + data_points = []OTS_DataPoint { + {0.0, 1.0}, + {1.0, 2.0}, + {2.0, 5.0}, + {3.0, 8.0}, + {4.0, 0.0}, + {5.0, 3.0}} + + raw_data = new (OTS_Data) + raw_data.TSData = data_points + + new_data = raw_data.Consolidate (2.0) + + new_data.Print() +} -- 2.11.0