RTBKit  0.9
Open-source framework to create real-time ad bidding systems.
core/agent_configuration/agent_config.h
00001 /* rtb_agent_config.h                                             -*- C++ -*-
00002    Jeremy Barnes, 24 March 2011
00003    Configuration for an RTB agent.
00004 */
00005 
00006 #ifndef __rtb_agent_config_h__
00007 #define __rtb_agent_config_h__
00008 
00009 #include <string>
00010 #include <vector>
00011 #include <set>
00012 #include "jml/arch/spinlock.h"
00013 #include "soa/jsoncpp/json.h"
00014 #include <boost/regex.hpp>
00015 #include <boost/regex/icu.hpp>
00016 #include "rtbkit/common/bid_request.h"
00017 #include "include_exclude.h"
00018 #include "rtbkit/common/account_key.h"
00019 
00020 namespace RTBKIT {
00021 
00022 
00023 struct BiddableSpots;
00024 struct AgentStats;
00025 struct ExchangeConnector;
00026 
00027 
00028 /*****************************************************************************/
00029 /* CREATIVE                                                                  */
00030 /*****************************************************************************/
00031 
00034 struct Creative {
00035     Creative(int width = 0, int height = 0,
00036              std::string name = "", int id = -1, int tagId = -1);
00037 
00038     // Three samples that can be used for testing...
00039     static const Creative sampleLB;
00040     static const Creative sampleBB;
00041     static const Creative sampleWS;
00042 
00043     void fromJson(const Json::Value & val);
00044     Json::Value toJson() const;
00045 
00046     Format format;
00047 
00049     int tagId;
00050 
00052     std::string name;
00053     int id;
00054 
00057     Json::Value providerConfig;
00058 
00060     mutable ML::Spinlock lock;
00061 
00063     std::map<std::string, std::shared_ptr<void> > providerData;
00064 
00065     template<typename T>
00066     const T * getProviderData(const std::string & provider) const
00067     {
00068         auto it = providerData.find(provider);
00069         if (it == providerData.end())
00070             throw ML::Exception("provider data for " + provider + " not found");
00071         if (it->second.get() == nullptr)
00072             throw ML::Exception("provider data for " + provider + " is null");
00073         
00074         return reinterpret_cast<const T *>(it->second.get());
00075     }
00076 
00078     Tags tags;
00079 
00081     TagFilterExpression eligibilityFilter;
00082 
00083     IncludeExclude<std::string> languageFilter;
00084     IncludeExclude<CachedRegex<boost::u32regex, Utf8String> > locationFilter;
00085     IncludeExclude<std::string> exchangeFilter;
00086 
00088     bool compatible(const AdSpot & spot) const;
00089 
00091     bool biddable(const std::string & exchange,
00092                   const std::string & protocolVersion) const;
00093 };
00094 
00095 
00096 /*****************************************************************************/
00097 /* USER PARTITION                                                            */
00098 /*****************************************************************************/
00099 
00104 struct UserPartition {
00105     UserPartition();
00106 
00107     void swap(UserPartition & other);
00108 
00109     void clear();
00110 
00111     enum HashOn {
00112         NONE,        
00113         RANDOM,      
00114 
00115         EXCHANGEID,  
00116         PROVIDERID   
00117     } hashOn;
00118 
00119     int modulus;     
00120 
00121     struct Interval {
00122         Interval(int first = 0, int last = 0)
00123             : first(first), last(last)
00124         {
00125         }
00126 
00127         int first, last;
00128 
00129         bool in(int val) const
00130         {
00131             return val >= first && val < last;
00132         }
00133 
00134         Json::Value toJson() const;
00135     };
00136 
00137     bool empty() const
00138     {
00139         return hashOn == NONE && modulus == 1 && includeRanges.size() == 1
00140             && includeRanges[0].first == 0 && includeRanges[0].last == 1;
00141     }
00142 
00144     std::vector<Interval> includeRanges;
00145 
00147     bool matches(const UserIds & ids) const;
00148 
00150     void fromJson(const Json::Value & json);
00151 
00153     Json::Value toJson() const;
00154 };
00155 
00156 
00157 /*****************************************************************************/
00158 /* BLACKLIST CONTROL                                                         */
00159 /*****************************************************************************/
00160 
00161 enum BlacklistType {
00162     BL_OFF,       
00163     BL_USER,      
00164     BL_USER_SITE  
00165 };
00166 
00167 enum BlacklistScope {
00168     BL_AGENT,      
00169     BL_ACCOUNT,    
00170 };
00171 
00172 
00173 /*****************************************************************************/
00174 /* BID CONTROL TYPE                                                          */
00175 /*****************************************************************************/
00176 
00177 enum BidControlType {
00178     BC_RELAY,       
00179     BC_RELAY_FIXED, 
00180     BC_FIXED        
00181 };
00182 
00183 
00184 /*****************************************************************************/
00185 /* BID RESULT FORMAT                                                         */
00186 /*****************************************************************************/
00187 
00188 enum BidResultFormat {
00189     BRF_FULL,         
00190     BRF_LIGHTWEIGHT,  
00191     BRF_NONE          
00192 };
00193 
00194 Json::Value toJson(BidResultFormat fmt);
00195 void fromJson(BidResultFormat & fmt, const Json::Value & j);
00196 
00197 
00198 /*****************************************************************************/
00199 /* AGENT CONFIG                                                              */
00200 /*****************************************************************************/
00201 
00205 struct AgentConfig {
00206     AgentConfig();
00207 
00208     static AgentConfig createFromJson(const Json::Value & json);
00209 
00210     void parse(const std::string & jsonStr);
00211     void fromJson(const Json::Value & json);
00212 
00213     Json::Value toJson(bool includeCreatives = true) const;
00214 
00215     AccountKey account;   
00216 
00217     bool test;            
00218     
00219     std::string roundRobinGroup;
00220     int roundRobinWeight;
00221 
00222     float bidProbability;
00223     float minTimeAvailableMs;
00224 
00225     int maxInFlight;
00226 
00227     std::vector<std::string> requiredIds;
00228 
00229     IncludeExclude<DomainMatcher> hostFilter;
00230     IncludeExclude<CachedRegex<boost::regex, std::string> > urlFilter;
00231     IncludeExclude<CachedRegex<boost::regex, std::string> > languageFilter;
00232     IncludeExclude<CachedRegex<boost::u32regex, Utf8String> > locationFilter;
00233 
00234     struct SegmentInfo {
00235         SegmentInfo()
00236             : excludeIfNotPresent(false)
00237         {
00238         }
00239 
00240         bool excludeIfNotPresent;
00241         SegmentList include;
00242         SegmentList exclude;
00243 
00246         IncludeExclude<std::string> applyToExchanges;
00247         
00248         IncludeExcludeResult process(const SegmentList & segments) const;
00249         
00250         void fromJson(const Json::Value & val);
00251         Json::Value toJson() const;
00252     };
00253 
00254     std::map<std::string, SegmentInfo> segments;
00255 
00256     IncludeExclude<std::string> exchangeFilter;
00257 
00258     IncludeExclude<OpenRTB::AdPosition> foldPositionFilter;
00259 
00260     SegmentInfo tagFilter;
00261 
00262     struct HourOfWeekFilter {
00263 
00264         HourOfWeekFilter();
00265 
00266         bool isIncluded(Date auctionDate) const;
00267 
00268         bool isDefault() const;  // true if all hours are 1
00269 
00270         void fromJson(const Json::Value & val);
00271         Json::Value toJson() const;
00272 
00273     private:
00274         std::bitset<168> hourBitmap;
00275     };
00276     
00277     HourOfWeekFilter hourOfWeekFilter;
00278 
00279     UserPartition userPartition;
00280 
00281     std::vector<Creative> creatives;
00282 
00283     BlacklistType blacklistType;
00284     BlacklistScope blacklistScope;
00285     double blacklistTime;
00286     
00287     bool hasBlacklist() const
00288     {
00289         return blacklistType != BL_OFF && blacklistTime > 0.0;
00290     }
00291 
00292     BidControlType bidControlType;
00293     uint32_t fixedBidCpmInMicros;
00294 
00295     IncludeExclude<std::string> augmentationFilter;
00296 
00297     struct AugmentationInfo {
00298         std::string name;
00299         Json::Value config;
00300 
00301         bool operator < (const AugmentationInfo & other) const
00302         {
00303             return name < other.name;
00304         }
00305     };
00306 
00310     void addAugmentation(const std::string & name,
00311                          Json::Value config = Json::Value());
00312 
00316     void addAugmentation(AugmentationInfo info);
00317 
00318     std::vector<AugmentationInfo> augmentations;
00319 
00321     Json::Value providerConfig;
00322 
00324     mutable ML::Spinlock lock;
00325 
00327     std::map<std::string, std::shared_ptr<void> > providerData;
00328 
00329     template<typename T>
00330     const T * getProviderData(const std::string & provider) const
00331     {
00332         auto it = providerData.find("rubicon");
00333         if (it == providerData.end())
00334             throw ML::Exception("provider data for " + provider + " not found");
00335         if (it->second.get() == nullptr)
00336             throw ML::Exception("provider data for " + provider + " is null");
00337         
00338         return reinterpret_cast<const T *>(it->second.get());
00339     }
00340 
00344     SegmentList visitChannels;
00345 
00347     bool includeUnmatchedVisits;
00348 
00350     BidResultFormat winFormat, lossFormat, errorFormat;
00351 
00355     BiddableSpots
00356     canBid(const ExchangeConnector * exchangeConnector,
00357            const std::vector<AdSpot> & imp,
00358            const std::string & exchange,
00359            const std::string & protocolVersion,
00360            const std::string & language,
00361            const Utf8String & location, uint64_t locationHash,
00362            ML::Lightweight_Hash<uint64_t, int> & locationCache) const;
00363 
00364 
00368     struct RequestFilterCache
00369     {
00370         RequestFilterCache(const BidRequest& request) :
00371             urlHash(hashString(request.url.c_str())),
00372 
00373             language(!request.language.empty() ?
00374                     request.language : "unspecified"),
00375             languageHash(hashString(request.language)),
00376 
00377             location(request.location.fullLocationString()),
00378             locationHash(hashString(location))
00379         {}
00380 
00381         uint64_t urlHash;
00382 
00383         std::string language;
00384         uint64_t languageHash;
00385 
00386         Utf8String location;
00387         uint64_t locationHash;
00388 
00389         // Cache of regex -> bool
00390         ML::Lightweight_Hash<uint64_t, int> urlFilter;
00391         ML::Lightweight_Hash<uint64_t, int> languageFilter;
00392         ML::Lightweight_Hash<uint64_t, int> locationFilter;
00393     };
00394 
00395     typedef std::function<void(const char*)> FilterStatFn;
00396 
00404     BiddableSpots
00405     isBiddableRequest(const ExchangeConnector * exchange,
00406                       const BidRequest& request,
00407                       AgentStats& stats,
00408                       RequestFilterCache& cache,
00409                       const FilterStatFn & doFilterStat = FilterStatFn()) const;
00410 };
00411 
00412 
00413 } // namespace RTBKIT
00414 
00415 #endif /* __rtb_agent_config_h__ */
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator