RTBKit  0.9
Open-source framework to create real-time ad bidding systems.
soa/types/periodic_utils.cc
00001 
00007 #include "periodic_utils.h"
00008 #include "jml/utils/parse_context.h"
00009 #include <boost/tuple/tuple.hpp>
00010 
00011 using namespace std;
00012 
00013 
00014 namespace Datacratic {
00015 
00016 std::pair<TimeGranularity, int>
00017 parsePeriod(const std::string & pattern)
00018 {
00019     TimeGranularity granularity;
00020     int number;
00021 
00022     ML::Parse_Context context(pattern,
00023                               pattern.c_str(),
00024                               pattern.c_str() + pattern.length());
00025 
00026     number = context.expect_int();
00027     
00028     if (number <= 0)
00029         context.exception("invalid time number: must be > 0");
00030 
00031     if (context.match_literal('x'))
00032     granularity = MILLISECONDS;
00033     else if (context.match_literal('s'))
00034         granularity = SECONDS;
00035     else if (context.match_literal('m'))
00036         granularity = MINUTES;
00037     else if (context.match_literal('h'))
00038         granularity = HOURS;
00039     else if (context.match_literal('d'))
00040         granularity = DAYS;
00041     else if (context.match_literal('w'))
00042         granularity = WEEKS;
00043     else if (context.match_literal('M'))
00044         granularity = MONTHS;
00045     else if (context.match_literal('y'))
00046         granularity = YEARS;
00047     else context.exception("excepted h, m, s, d, w, M, y or x");
00048 
00049     context.expect_eof();
00050 
00051     return make_pair(granularity, number);
00052 }
00053 
00054 std::pair<Date, double>
00055 findPeriod(Date current, const std::string & period)
00056 {
00057     TimeGranularity p;
00058     int n;
00059     boost::tie(p, n) = parsePeriod(period);
00060     return findPeriod(current, p, n);
00061 }
00062 
00063 std::pair<Date, double>
00064 findPeriod(Date current, TimeGranularity granularity, int number)
00065 {
00066     // Find where the current period starts
00067 
00068     tm t = current.toTm();
00069 
00070     // Remove fractional seconds
00071     Date result = current;
00072     int64_t seconds = result.secondsSinceEpoch();
00073     result = Date::fromSecondsSinceEpoch(seconds);
00074 
00075     //Date unadjusted = result;
00076 
00077     double interval;
00078 
00079     switch (granularity) {
00080     case DAYS:
00081         if (number != 1)
00082             throw ML::Exception("only 1d is supported for days");
00083         // Go to the start of the day
00084         result.addSeconds(-(3600 * t.tm_hour + 60 * t.tm_min + t.tm_sec));
00085         
00086         // Go to day
00087         interval = 3600 * 24 * number;
00088 
00089         break;
00090     case HOURS:
00091         // Go to the start of the hour
00092         result.addSeconds(-(60 * t.tm_min + t.tm_sec));
00093 
00094         // Go to hour number n of the day
00095         result.addSeconds(-3600 * (t.tm_hour % number));
00096 
00097         interval = 3600 * number;
00098 
00099         break;
00100 
00101     case MINUTES:
00102         // Go to the start of the minute
00103         result.addSeconds(-t.tm_sec);
00104 
00105         // Go to the next multiple of minutes
00106         result.addSeconds(-60 * (t.tm_min % number));
00107 
00108         interval = 60 * number;
00109 
00110         break;
00111 
00112     case SECONDS:
00113         //cerr << "seconds: t.tm_sec = " << t.tm_sec    
00114         //     << " number = " << number << " before = "
00115         //     << result;
00116         result.addSeconds(-(t.tm_sec % number));
00117         //cerr <<" after = " << result << " current = "
00118         //     << current << endl;
00119 
00120         interval = number;
00121         break;
00122 
00123     case MILLISECONDS:
00124     interval = number / 1000.0;
00125 
00126     result = current.quantized(interval);
00127     if (result > current)
00128         result.addSeconds(-interval);
00129 
00130     break;
00131 
00132     default:
00133         throw ML::Exception("that granualrity is not supported");
00134     }
00135 
00136     return make_pair(result, interval);
00137 }
00138 
00139 std::string
00140 filenameFor(const Date & date, const std::string & pattern)
00141 {
00142     return date.print(pattern);
00143 }
00144 
00145 } // namespace Datacratic
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator