Initial commit.
[otsdb-go.git] / compact.go
1 package main
2
3 import (
4   "fmt"
5   "os"
6 )
7
8 type OTS_DataPoint struct {
9   TimeStamp float64
10   Rate      float64
11 }
12
13 type OTS_Data struct {
14   TSData []OTS_DataPoint
15 }
16
17 /* Functions for the sort interface. */
18 func (obj *OTS_Data) Len () int {
19   return (len (obj.TSData))
20 }
21
22 func (obj *OTS_Data) Less (i, j int) bool {
23   if obj.TSData[i].TimeStamp < obj.TSData[j].TimeStamp {
24     return true
25   }
26   return false
27 }
28
29 func (obj *OTS_Data) Swap (i, j int) {
30   tmp := obj.TSData[i]
31   obj.TSData[i] = obj.TSData[j]
32   obj.TSData[j] = tmp
33 }
34
35 func Fmod64 (a float64, b float64) float64 {
36   tmp := int (a / b)
37   return b * float64 (tmp)
38 }
39
40 func (obj *OTS_Data) Write (name string) os.Error {
41   fd, err := os.OpenFile(name, os.O_WRONLY, 0666)
42   if err != nil {
43     return err
44   }
45
46   for i := 0; i < len (obj.TSData); i++ {
47     data_point := obj.TSData[i]
48     str := fmt.Sprintf ("%.3f,%g\n", data_point.TimeStamp, data_point.Rate)
49
50     fd.WriteString (str)
51   }
52
53   fd.Close ()
54   return nil
55 }
56
57 func ReadFile (name string) (obj *OTS_Data, err os.Error) {
58 }
59
60 func (raw_data *OTS_Data) Consolidate (interval float64) *OTS_Data {
61   if interval <= 0.0 {
62     return nil
63   }
64
65   ts_raw_first := raw_data.TSData[0].TimeStamp
66   ts_raw_last  := ts_raw_first
67
68   /* Determine the first and last data point.
69    * XXX: In the future, this should be a sorted list! */
70   for i := 1; i < len (raw_data.TSData); i++ {
71     data_point := raw_data.TSData[i]
72
73     if ts_raw_first > data_point.TimeStamp {
74       ts_raw_first = data_point.TimeStamp
75     }
76
77     if ts_raw_last < data_point.TimeStamp {
78       ts_raw_last = data_point.TimeStamp
79     }
80   }
81
82   fmt.Printf ("ts_raw_first = %g; ts_raw_last = %g;\n",
83       ts_raw_first, ts_raw_last)
84
85   /* Determine the timespan the consolidated data will span. */
86   ts_csl_first := Fmod64 (ts_raw_first, interval)
87   ts_csl_last  := Fmod64 (ts_raw_last,  interval)
88   if ts_csl_last < ts_raw_last {
89     ts_csl_last += interval
90   }
91
92   fmt.Printf ("ts_csl_first = %g; ts_csl_last = %g;\n",
93       ts_csl_first, ts_csl_last)
94
95   intervals_num := int ((ts_csl_last - ts_csl_first) / interval)
96   fmt.Printf ("Got a %gs timespan (%d intervals).\n",
97       ts_csl_last - ts_csl_first, intervals_num)
98
99   /* Allocate return structure */
100   ret_data := new (OTS_Data)
101   ret_data.TSData = make ([]OTS_DataPoint, intervals_num)
102
103   /* FIXME: This is currently a O(n^2) algorithm. It should instead be a O(n)
104    * algorithm. This is possible if raw_data is sorted (which, obviously, is a
105    * O(n log(n)) task). */
106   for i := 0; i < intervals_num; i++ {
107       ts := ts_csl_first + (float64 (i) * interval)
108       sum := 0.0
109       num := 0.0
110
111       fmt.Printf ("Building data for interval %g.\n", ts)
112
113       ret_data.TSData[i].TimeStamp = ts
114
115       for j := 0; j < len (raw_data.TSData); j++ {
116         data_point := raw_data.TSData[j]
117
118         if ((data_point.TimeStamp < ts) || (data_point.TimeStamp >= (ts + interval))) {
119           continue
120         }
121
122         sum += data_point.Rate
123         num += 1.0
124       }
125
126       /* TODO: Be more clever about how this consolidated rate is computed. */
127       if num > 0.0 {
128         ret_data.TSData[i].Rate = sum / num
129       }
130   }
131
132   return ret_data
133 }
134
135 func (obj *OTS_Data) Print () {
136   for i := 0; i < len (obj.TSData); i++ {
137     data_point := obj.TSData[i]
138     fmt.Printf ("[%g] %g\n", data_point.TimeStamp, data_point.Rate)
139   }
140 } /* Print () */
141
142 func main () {
143   var data_points []OTS_DataPoint
144   var raw_data     *OTS_Data
145   var new_data     *OTS_Data
146
147   data_points = []OTS_DataPoint {
148     {0.0,  1.0},
149     {1.0,  2.0},
150     {2.0,  5.0},
151     {3.0,  8.0},
152     {4.0,  0.0},
153     {5.0,  3.0}}
154
155   raw_data = new (OTS_Data)
156   raw_data.TSData = data_points
157
158   new_data = raw_data.Consolidate (2.0)
159
160   new_data.Print()
161 }