RTBKit  0.9
Open-source framework to create real-time ad bidding systems.
soa/service/port_range_service.cc
00001 
00009 #include "port_range_service.h"
00010 #include "soa/jsoncpp/value.h"
00011 #include "soa/jsoncpp/reader.h"
00012 #include "jml/utils/exc_assert.h"
00013 
00014 #include <fstream>
00015 #include <cstring>
00016 
00017 using namespace std;
00018 using namespace ML;
00019 
00020 namespace Datacratic {
00021 
00022 
00023 /******************************************************************************/
00024 /* PORT RANGE                                                                 */
00025 /******************************************************************************/
00026 
00027 Json::Value
00028 PortRange::
00029 toJson() const
00030 {
00031     if (last == first + 1)
00032         return first;
00033 
00034     Json::Value result;
00035     result[0] = "range";
00036     result[1] = first;
00037     result[2] = last;
00038     return result;
00039 }
00040 
00041 PortRange
00042 PortRange::
00043 fromJson(const Json::Value & val)
00044 {
00045     if (val.isNull())
00046         return PortRange();
00047     else if (val.isNumeric())
00048         return val.asInt();
00049     else if (val.isArray()) {
00050         string type = val[0].asString();
00051         if (type == "range") {
00052             int first = val[1].asInt();
00053             int last = val[2].asInt();
00054             return PortRange(first, last);
00055         }
00056     }
00057     throw ML::Exception("unknown port range " + val.toString());
00058 }
00059 
00060 
00061 /******************************************************************************/
00062 /* UTILS                                                                      */
00063 /******************************************************************************/
00064 
00065 namespace {
00066 
00067 void dumpRangeMap(ostream& stream, const map<string, PortRange> rangeMap)
00068 {
00069     for (const auto& entry : rangeMap) {
00070         stream << entry.first << ": ";
00071 
00072         if (entry.second.last - entry.second.first > 1) {
00073             stream << "["
00074                 << entry.second.first << ", " << entry.second.last
00075                 << "]";
00076         }
00077         else stream << entry.second.first;
00078 
00079         stream << endl;
00080     }
00081 }
00082 
00083 } // namespace anonymous
00084 
00085 /******************************************************************************/
00086 /* DEFAULT PORT RANGE SERVICE                                                 */
00087 /******************************************************************************/
00088 
00089 DefaultPortRangeService::
00090 DefaultPortRangeService(unsigned rangeSize) :
00091     rangeSize(rangeSize), currentPort(15000)
00092 {}
00093 
00094 PortRange
00095 DefaultPortRangeService::
00096 getRange(const string& name)
00097 {
00098     lock_guard<mutex> guard(lock);
00099 
00100     PortRange newRange(currentPort, currentPort + rangeSize);
00101     auto ret = rangeMap.insert(make_pair(name, newRange));
00102 
00103     if (ret.second) currentPort += rangeSize;
00104 
00105     return ret.first->second;
00106 }
00107 
00108 void
00109 DefaultPortRangeService::
00110 dump(ostream& stream) const
00111 {
00112     lock_guard<mutex> guard(lock);
00113 
00114     dumpRangeMap(stream, rangeMap);
00115 }
00116 
00117 
00118 /******************************************************************************/
00119 /* JSON PORT RANGE SERVICE                                                    */
00120 /******************************************************************************/
00121 
00122 JsonPortRangeService::
00123 JsonPortRangeService(const Json::Value& json)
00124 {
00125     vector<string> members = json.getMemberNames();
00126 
00127     for (size_t i = 0; i < members.size(); ++i) {
00128         const Json::Value& entry = json[members[i]];
00129 
00130         PortRange newRange;
00131 
00132         if (entry.isArray()) {
00133             newRange.first = entry[0].asInt();
00134             newRange.last = entry[1].asInt();
00135         }
00136         else if (entry.isInt()) {
00137             newRange = entry.asInt();
00138         }
00139         else ExcCheck(false, "Invalid entry type.");
00140 
00141         auto ret = rangeMap.insert(make_pair(members[i], newRange));
00142 
00143         ExcAssert(ret.second);
00144     }
00145 }
00146 
00147 PortRange
00148 JsonPortRangeService::
00149 getRange(const string& name)
00150 {
00151     auto it = rangeMap.find(name);
00152     ExcCheck(it != rangeMap.end(), "No port range specified for " + name);
00153 
00154     return it->second;
00155 }
00156 
00157 void
00158 JsonPortRangeService::
00159 dump(ostream& stream) const
00160 {
00161     dumpRangeMap(stream, rangeMap);
00162 }
00163 
00164 
00165 } // namepsace Datacratic
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator