~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Open Mash Cross Reference
mash/tgw/BidderHouse.cc

Component: ~ [ mash ] ~ [ apps ] ~ [ gsm ] ~ [ lib ] ~ [ otcl ] ~ [ srm ] ~ [ tcl8.3 ] ~ [ tclcl ] ~ [ tk8.3 ] ~ [ tutorials ] ~

  1 /*
  2  * BidderHouse.cc --
  3  *
  4  *      FIXME: This file needs a description here.
  5  *
  6  * Copyright (c) 2001-2002 The Regents of the University of California.
  7  * All rights reserved.
  8  *
  9  * Redistribution and use in source and binary forms, with or without
 10  * modification, are permitted provided that the following conditions are met:
 11  *
 12  * A. Redistributions of source code must retain the above copyright notice,
 13  *    this list of conditions and the following disclaimer.
 14  * B. Redistributions in binary form must reproduce the above copyright notice,
 15  *    this list of conditions and the following disclaimer in the documentation
 16  *    and/or other materials provided with the distribution.
 17  * C. Neither the names of the copyright holders nor the names of its
 18  *    contributors may be used to endorse or promote products derived from this
 19  *    software without specific prior written permission.
 20  *
 21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
 22  * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 23  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 24  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
 25  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 31  * POSSIBILITY OF SUCH DAMAGE.
 32  */
 33 
 34 #include "BidderHouse.h"
 35 #include "pipe_rend.h"
 36 
 37 static class BidderHouseClass : public TclClass {
 38 public:
 39   BidderHouseClass() : TclClass ("BidderHouse") {}
 40   TclObject* create(int argc, const char*const* argv) {
 41     BidderHouse* house;
 42     if (argc == 5)
 43       house = new BidderHouse(atoi(argv[4]));
 44     else
 45       house = new BidderHouse(128000);
 46     //    ASSERT(house != NULL);
 47     return house;
 48   }
 49 private:
 50 } BidderHouseClass;
 51 
 52 int
 53 BidderHouse::command(int argc, const char*const* argv) {
 54   Tcl& tcl = Tcl::instance();
 55   if (argc == 2) {
 56     if (strcmp(argv[1], "hold_bid") == 0) {
 57       // this is called once at the start and it keeps calling itself after that.
 58       tcl.evalf("after %d %s hold_bid", BID_INTERVAL, name());
 59       sellBandwidth();
 60       return (TCL_OK);
 61     } else if (strcmp(argv[1], "update_bw") == 0) {
 62       // called once at start and calls itself after that. Update the bandwidth display.
 63       tcl.evalf("after %d %s update_bw", UPDATE_INTERVAL, name());
 64       getBandwidthUsage();
 65       return (TCL_OK);
 66     }
 67   } else if (argc == 4) {
 68     if (strcmp(argv[1], "set_priority") == 0) {
 69       // sets the wage, is called when the slider is moved...
 70       PipeRenderer* src = (PipeRenderer*)TclObject::lookup(argv[2]);
 71       setPriority(src, atoi(argv[3]));
 72       return (TCL_OK);
 73     } 
 74   } 
 75   return (TCL_ERROR);
 76 }
 77 
 78 // add a new source into the auction.
 79 void
 80 BidderHouse::addSource(PipeRenderer* msource) {
 81   Bidder* source = new Bidder(0,0,0,0,0,msource);
 82   sources.push_back(source);
 83 }
 84 
 85 // called by the source to tell the auction house how much bandwidth this
 86 // particular source wants.
 87 void
 88 BidderHouse::setDiffCount(PipeRenderer* msource,
 89                          int diffCount, int meanDiffSize)
 90 {
 91   Bidder* source = lookupSource(msource);
 92   source->diffsWant = diffCount;
 93   source->diffSize = meanDiffSize;
 94   //  printf("setting Diff count for %d to %d\n",source, diffCount);
 95 }
 96 
 97 Bidder*
 98 BidderHouse::lookupSource(PipeRenderer* msource)
 99 {
100   for (vector<Bidder*>::iterator e = sources.begin();
101        e != sources.end(); e++) {
102     if ((*e)->msource == msource)
103       return *e;
104   }
105 
106   //  assert(0);
107   return NULL;
108 }
109 
110 // called after the auction. tells the source to send its data and
111 // then updates all relevant fields.
112 void
113 BidderHouse::giveBWtoSource(Bidder* source, int price) {
114   if ((source->diffsWant == 0) || (source->money == 0) || (source->wage == 0))
115     return;
116 
117   int temp = source->diffsWant * source->diffSize;
118   bytesToSend -= temp;
119   source->bandwidth += temp*8;
120   source->money -= price*temp;
121   source->msource->giveToEncoder(source->diffsWant);
122   source->diffsWant = 0;
123   //printf("sold bw to %d, money taken is %d, price is %d\n\n",source, price*temp,price);
124 }
125 
126 // sorts the bidders to find the highest price.
127 void
128 BidderHouse::lotterySort(int num_of_sources) {
129   // simple order n squared sort of the arrays by price
130   int temp, temp2, u_holder, p_holder;
131   Bidder* s_holder;
132   for (temp = 0; temp < (num_of_sources-1); temp++) {
133     for (temp2 = 0; temp2 < (num_of_sources-1); temp2++) {
134       if (lottery_price[temp2] < lottery_price[temp2+1]) {
135         s_holder = lottery_source[temp2];
136         lottery_source[temp2] = lottery_source[temp2+1];
137         lottery_source[temp2+1] = s_holder;
138         u_holder = lottery_units[temp2];
139         lottery_units[temp2] = lottery_units[temp2+1];
140         lottery_units[temp2+1] = u_holder;
141         p_holder = lottery_price[temp2];
142         lottery_price[temp2] = lottery_price[temp2+1];
143         lottery_price[temp2+1] = p_holder;
144       }
145     }
146   }
147 }
148 
149 // called regularly based on BID_INTERVAL and does the actual auction.
150 void
151 BidderHouse::sellBandwidth()
152 {
153   int totalDemand = 0;
154   int temp,x;
155   vector<Bidder*>::iterator e;
156   Bidder* source;
157 
158   // increment the bandwidth pool only if it doesn't allready have too much saved up.
159   if (bytesToSend < (MAX_BW_SECONDS*bps)/8) 
160     //increment the amount of bandwidth we have available
161     bytesToSend += (bps * BID_INTERVAL) / (1000 * 8);
162   
163   // update the money for each bidder.
164   for (e = sources.begin(); e != sources.end(); e++) {
165     source = *e;
166     // insure that no one has too much money saved
167     if (source->money < MAX_SAVED_MONEY)
168       // pay everyone
169       source->money += (source->wage*WAGE_FACTOR);
170     //    printf("source %d has %d money\n",(int)source, source->money);
171     // find how many total bytes we want to send
172     totalDemand += source->diffsWant * source->diffSize;
173   }
174   
175   if ((totalDemand == 0) || (bytesToSend == 0)) {
176     //    printf("not sending anything because no demand or no bw left\n");
177     return;
178   } else if (totalDemand > bytesToSend) {
179     // setup the arrays for doing the market
180     int num_of_sources = 0;
181     for (e = sources.begin(); e != sources.end(); e++,num_of_sources++) {
182       source = *e;
183       lottery_source[num_of_sources] = source;
184       lottery_units[num_of_sources] = source->diffsWant * source->diffSize;
185       if (lottery_units[num_of_sources] == 0)
186         lottery_price[num_of_sources] = 0;
187       else
188         lottery_price[num_of_sources] = source->money/lottery_units[num_of_sources];
189       //printf("source %d has %d money, %d units, %d diffs, and can pay %d\n",lottery_source[num_of_sources],source->money,lottery_units[num_of_sources],source->diffsWant,lottery_price[num_of_sources]);
190     }
191 
192     // sort the array
193     lotterySort(num_of_sources);
194 
195     // go up the array till you find the point at which you go over units
196     temp = 0;
197     for (x = 0; x < num_of_sources; x++) {
198       temp += lottery_units[x];
199       if (temp > bytesToSend)
200         break;
201     }
202 
203     // pick the price right below that point.
204     if (x > 0) {
205       for (temp=0; temp<x; temp++) {
206         giveBWtoSource(lottery_source[temp], lottery_price[x-1]);
207       }
208     } else {
209       //printf("not enough bw. wants %d, but has %d\n\n", lottery_units[0],bytesToSend);
210     }
211   } else {
212     // give everyone what they want...
213     for (e = sources.begin(); e != sources.end(); e++) {
214       giveBWtoSource(*e, 1);
215     }
216   }
217 }
218 
219 // forwards the bandwidth usage data to the GUI to be displayed.
220 void
221 BidderHouse::getBandwidthUsage()
222 {
223   for (vector<Bidder*>::iterator e = sources.begin();
224        e != sources.end(); e++) {
225     Bidder* source = *e;
226     int calculated_bps = (source->bandwidth * 1000)/UPDATE_INTERVAL;
227     source->bandwidth = 0;
228     source->msource->bandwidthUsage(calculated_bps/1000);
229     //    Tcl::instance().evalf("puts \"set bandwidth to %d\"", source->bandwidth/1000);
230   }
231 }
232 
233 // called from the UI to set a source's wage.
234 void
235 BidderHouse::setPriority(PipeRenderer* msource, int percentage)
236 {
237   lookupSource(msource)->wage = percentage;
238 }
239 
240 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.