00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00047 #include <config.h>
00048 #include <drizzled/plugin.h>
00049 #include <drizzled/statistics_variables.h>
00050 #include "scoreboard.h"
00051
00052 #include <math.h>
00053
00054 using namespace drizzled;
00055 using namespace std;
00056
00057 Scoreboard::Scoreboard(uint32_t in_number_sessions, uint32_t in_number_buckets)
00058 :
00059 number_sessions(in_number_sessions),
00060 number_buckets(in_number_buckets)
00061 {
00062
00063
00064 number_per_bucket= static_cast<uint32_t> ( ceil( static_cast<double>(number_sessions) / static_cast<double>(number_buckets) ) );
00065
00066 vector_of_scoreboard_vectors.reserve(number_buckets);
00067
00068 for (uint32_t j= 0; j < number_buckets; ++j)
00069 {
00070 vector<ScoreboardSlot* > *scoreboard_vector= new vector<ScoreboardSlot*>;
00071
00072 scoreboard_vector->reserve(number_per_bucket);
00073
00074 for (uint32_t h= 0; h < number_per_bucket; ++h)
00075 scoreboard_vector->push_back(new ScoreboardSlot);
00076
00077
00078 vector_of_scoreboard_vectors.push_back(scoreboard_vector);
00079 }
00080
00081 vector_of_scoreboard_locks.reserve(number_buckets);
00082
00083 for (uint32_t k= 0; k < number_buckets; ++k)
00084 vector_of_scoreboard_locks.push_back(new boost::shared_mutex);
00085
00086
00087 size_t statusVarsSize= sizeof(StatusVars) + sizeof(system_status_var);
00088 size_t userCommandsSize= sizeof(UserCommands) + sizeof(uint64_t) * SQLCOM_END;
00089
00090 scoreboard_size_bytes= (statusVarsSize + userCommandsSize) * number_per_bucket * number_buckets;
00091 }
00092
00093 Scoreboard::~Scoreboard()
00094 {
00095 BOOST_FOREACH(std::vector<ScoreboardSlot*>* it0, vector_of_scoreboard_vectors)
00096 {
00097 BOOST_FOREACH(ScoreboardSlot* it, *it0)
00098 delete it;
00099 delete it0;
00100 }
00101 BOOST_FOREACH(boost::shared_mutex* it, vector_of_scoreboard_locks)
00102 delete it;
00103 }
00104
00105 uint32_t Scoreboard::getBucketNumber(Session *session) const
00106 {
00107 return session->getSessionId() % number_buckets;
00108 }
00109
00110 ScoreboardSlot* Scoreboard::findScoreboardSlotToLog(Session *session)
00111 {
00112
00113 uint32_t bucket_number= getBucketNumber(session);
00114
00115
00116 vector<ScoreboardSlot* > *scoreboard_vector= vector_of_scoreboard_vectors.at(bucket_number);
00117
00118
00119 int32_t session_scoreboard_slot= session->getScoreboardIndex();
00120
00121 if (session_scoreboard_slot != -1)
00122 return scoreboard_vector->at(session_scoreboard_slot);
00123
00124 boost::shared_mutex* LOCK_scoreboard_vector= vector_of_scoreboard_locks.at(bucket_number);
00125 LOCK_scoreboard_vector->lock();
00126
00127 int32_t slot_index= 0;
00128 for (vector<ScoreboardSlot*>::iterator it= scoreboard_vector->begin(); it != scoreboard_vector->end(); ++it, ++slot_index)
00129 {
00130 ScoreboardSlot& slot= **it;
00131 if (slot.isInUse())
00132 continue;
00133 slot.setInUse(true);
00134 slot.setSessionId(session->getSessionId());
00135 slot.setUser(session->user()->username());
00136 slot.setIp(session->user()->address());
00137 session->setScoreboardIndex(slot_index);
00138 LOCK_scoreboard_vector->unlock();
00139 return &slot;
00140 }
00141
00142 LOCK_scoreboard_vector->unlock();
00143
00144
00145
00146 return NULL;
00147 }
00148
00149 ScoreboardSlot* Scoreboard::findOurScoreboardSlot(Session *session)
00150 {
00151
00152 int32_t session_scoreboard_slot= session->getScoreboardIndex();
00153 if (session_scoreboard_slot == -1)
00154 return NULL;
00155 return vector_of_scoreboard_vectors.at(getBucketNumber(session))->at(session_scoreboard_slot);
00156 }