Drizzled Public API Documentation

scoreboard.cc
1 /*
2  * Copyright (C) 2010 Joseph Daly <skinny.moey@gmail.com>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * * Redistributions of source code must retain the above copyright notice,
9  * this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13  * * Neither the name of Joseph Daly nor the names of its contributors
14  * may be used to endorse or promote products derived from this software
15  * without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27  * THE POSSIBILITY OF SUCH DAMAGE.
28  *
29  */
30 
47 #include <config.h>
48 #include <drizzled/plugin.h>
49 #include <drizzled/statistics_variables.h>
50 #include "scoreboard.h"
51 
52 #include <math.h>
53 
54 using namespace drizzled;
55 using namespace std;
56 
57 Scoreboard::Scoreboard(uint32_t in_number_sessions, uint32_t in_number_buckets)
58  :
59  number_sessions(in_number_sessions),
60  number_buckets(in_number_buckets)
61 {
62 
63  /* calculate the number of elements in each bucket */
64  number_per_bucket= static_cast<uint32_t> ( ceil( static_cast<double>(number_sessions) / static_cast<double>(number_buckets) ) );
65 
66  vector_of_scoreboard_vectors.reserve(number_buckets);
67  /* populate the vector of scoreboard vectors */
68  for (uint32_t j= 0; j < number_buckets; ++j)
69  {
70  vector<ScoreboardSlot* > *scoreboard_vector= new vector<ScoreboardSlot*>;
71 
72  scoreboard_vector->reserve(number_per_bucket);
73  /* preallocate the individual vectors */
74  for (uint32_t h= 0; h < number_per_bucket; ++h)
75  scoreboard_vector->push_back(new ScoreboardSlot);
76 
77  /* insert the vector into the vector of scoreboard vectors */
78  vector_of_scoreboard_vectors.push_back(scoreboard_vector);
79  }
80 
81  vector_of_scoreboard_locks.reserve(number_buckets);
82  /* populate the scoreboard locks vector each ScoreboardSlot vector gets a lock */
83  for (uint32_t k= 0; k < number_buckets; ++k)
84  vector_of_scoreboard_locks.push_back(new boost::shared_mutex);
85 
86  /* calculate the approximate memory allocation of the scoreboard */
87  size_t statusVarsSize= sizeof(StatusVars) + sizeof(system_status_var);
88  size_t userCommandsSize= sizeof(UserCommands) + sizeof(uint64_t) * SQLCOM_END;
89 
90  scoreboard_size_bytes= (statusVarsSize + userCommandsSize) * number_per_bucket * number_buckets;
91 }
92 
93 Scoreboard::~Scoreboard()
94 {
95  BOOST_FOREACH(std::vector<ScoreboardSlot*>* it0, vector_of_scoreboard_vectors)
96  {
97  BOOST_FOREACH(ScoreboardSlot* it, *it0)
98  delete it;
99  delete it0;
100  }
101  BOOST_FOREACH(boost::shared_mutex* it, vector_of_scoreboard_locks)
102  delete it;
103 }
104 
105 uint32_t Scoreboard::getBucketNumber(Session *session) const
106 {
107  return session->getSessionId() % number_buckets;
108 }
109 
111 {
112  /* our bucket */
113  uint32_t bucket_number= getBucketNumber(session);
114 
115  /* our vector corresponding to bucket_number */
116  vector<ScoreboardSlot* > *scoreboard_vector= vector_of_scoreboard_vectors.at(bucket_number);
117 
118  /* Check if this session has already claimed a slot */
119  int32_t session_scoreboard_slot= session->getScoreboardIndex();
120 
121  if (session_scoreboard_slot != -1)
122  return scoreboard_vector->at(session_scoreboard_slot);
123 
124  boost::shared_mutex* LOCK_scoreboard_vector= vector_of_scoreboard_locks.at(bucket_number);
125  LOCK_scoreboard_vector->lock();
126 
127  int32_t slot_index= 0;
128  for (vector<ScoreboardSlot*>::iterator it= scoreboard_vector->begin(); it != scoreboard_vector->end(); ++it, ++slot_index)
129  {
130  ScoreboardSlot& slot= **it;
131  if (slot.isInUse())
132  continue;
133  slot.setInUse(true);
134  slot.setSessionId(session->getSessionId());
135  slot.setUser(session->user()->username());
136  slot.setIp(session->user()->address());
137  session->setScoreboardIndex(slot_index);
138  LOCK_scoreboard_vector->unlock();
139  return &slot;
140  }
141 
142  LOCK_scoreboard_vector->unlock();
143 
144  /* its possible we did not claim a slot if the scoreboard size is somehow smaller then the
145  active connections */
146  return NULL;
147 }
148 
150 {
151  /* Check if this session has already claimed a slot */
152  int32_t session_scoreboard_slot= session->getScoreboardIndex();
153  if (session_scoreboard_slot == -1)
154  return NULL;
155  return vector_of_scoreboard_vectors.at(getBucketNumber(session))->at(session_scoreboard_slot);
156 }
ScoreboardSlot * findScoreboardSlotToLog(drizzled::Session *session)
Definition: scoreboard.cc:110
session_id_t getSessionId() const
Definition: session.h:644
ScoreboardSlot * findOurScoreboardSlot(drizzled::Session *session)
Definition: scoreboard.cc:149