~drizzle-trunk/drizzle/development

1320.5.6 by Joe Daly
first pass at using a module vector approach of scoreboard
1
/*
1999.6.1 by kalebral at gmail
update Copyright strings to a more common format to help with creating the master debian copyright file
2
 * Copyright (C) 2010 Joseph Daly <skinny.moey@gmail.com>
1320.5.6 by Joe Daly
first pass at using a module vector approach of scoreboard
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
1320.5.13 by Joe Daly
add description and comments to various files
31
/**
32
 * @details
33
 *
34
 * The scoreboard is a pre-allocated vector of vectors of ScoreBoardSlots. It
1320.5.17 by Joe Daly
clean up some unneeded destructors and add update comments
35
 * can be thought of as a vector of buckets where each bucket contains
1320.5.13 by Joe Daly
add description and comments to various files
36
 * pre-allocated ScoreBoardSlots. To determine which bucket gets used for
37
 * recording statistics the modulus operator is used on the session_id. This 
38
 * will result in a bucket to search for a unused ScoreBoardSlot. 
39
 * 
40
 * Locking  
41
 *   
42
 * Each bucket has a its own lock this allows a search of bucket 1 and bucket 2
43
 * to happen concurrently.  
44
 *
45
 */
46
2173.2.1 by Monty Taylor
Fixes incorrect usage of include
47
#include <config.h>
1561.3.1 by Joe Daly
add status_vars to scoreboard, initial pass
48
#include <drizzled/plugin.h>
2241.3.1 by Olaf van der Spek
Refactor Session::status_var
49
#include <drizzled/statistics_variables.h>
1320.5.6 by Joe Daly
first pass at using a module vector approach of scoreboard
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 */
1711.7.2 by Joseph Daly
add memory usage
64
  number_per_bucket= static_cast<uint32_t> ( ceil( static_cast<double>(number_sessions) / static_cast<double>(number_buckets) ) );
1320.5.6 by Joe Daly
first pass at using a module vector approach of scoreboard
65
2318.8.8 by Olaf van der Spek
Refactor Scoreboard
66
  vector_of_scoreboard_vectors.reserve(number_buckets);
1320.5.6 by Joe Daly
first pass at using a module vector approach of scoreboard
67
  /* populate the vector of scoreboard vectors */
1320.5.20 by Joe Daly
fix incrementors
68
  for (uint32_t j= 0; j < number_buckets; ++j)
1320.5.6 by Joe Daly
first pass at using a module vector approach of scoreboard
69
  {
2318.8.8 by Olaf van der Spek
Refactor Scoreboard
70
    vector<ScoreboardSlot* > *scoreboard_vector= new vector<ScoreboardSlot*>;
1320.5.6 by Joe Daly
first pass at using a module vector approach of scoreboard
71
2318.8.8 by Olaf van der Spek
Refactor Scoreboard
72
    scoreboard_vector->reserve(number_per_bucket);
1320.5.6 by Joe Daly
first pass at using a module vector approach of scoreboard
73
    /* preallocate the individual vectors */
1320.5.20 by Joe Daly
fix incrementors
74
    for (uint32_t h= 0; h < number_per_bucket; ++h)
2318.8.8 by Olaf van der Spek
Refactor Scoreboard
75
      scoreboard_vector->push_back(new ScoreboardSlot);
1320.5.6 by Joe Daly
first pass at using a module vector approach of scoreboard
76
77
    /* insert the vector into the vector of scoreboard vectors */
2318.8.8 by Olaf van der Spek
Refactor Scoreboard
78
    vector_of_scoreboard_vectors.push_back(scoreboard_vector); 
1320.5.6 by Joe Daly
first pass at using a module vector approach of scoreboard
79
  }
80
  
2318.8.8 by Olaf van der Spek
Refactor Scoreboard
81
  vector_of_scoreboard_locks.reserve(number_buckets);
1320.5.6 by Joe Daly
first pass at using a module vector approach of scoreboard
82
  /* populate the scoreboard locks vector each ScoreboardSlot vector gets a lock */
1320.5.20 by Joe Daly
fix incrementors
83
  for (uint32_t k= 0; k < number_buckets; ++k)
2318.8.8 by Olaf van der Spek
Refactor Scoreboard
84
    vector_of_scoreboard_locks.push_back(new boost::shared_mutex);
1711.7.2 by Joseph Daly
add memory usage
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;
1320.5.6 by Joe Daly
first pass at using a module vector approach of scoreboard
91
}
92
93
Scoreboard::~Scoreboard()
94
{
2318.8.8 by Olaf van der Spek
Refactor Scoreboard
95
  BOOST_FOREACH(std::vector<ScoreboardSlot*>* it0, vector_of_scoreboard_vectors)
96
  {
97
    BOOST_FOREACH(ScoreboardSlot* it, *it0)
98
      delete it; 
99
    delete it0;
1320.5.9 by Joe Daly
add destructors
100
  }
2318.8.8 by Olaf van der Spek
Refactor Scoreboard
101
  BOOST_FOREACH(boost::shared_mutex* it, vector_of_scoreboard_locks)
102
    delete it;
1320.5.6 by Joe Daly
first pass at using a module vector approach of scoreboard
103
}
104
2318.8.8 by Olaf van der Spek
Refactor Scoreboard
105
uint32_t Scoreboard::getBucketNumber(Session *session) const
1491.4.6 by Joe Daly
rework stats_schema use static char * for command strings
106
{
2318.8.8 by Olaf van der Spek
Refactor Scoreboard
107
  return session->getSessionId() % number_buckets;
1491.4.6 by Joe Daly
rework stats_schema use static char * for command strings
108
}
109
1561.3.20 by Joe Daly
add a index in session.h this will allow repeated lookups without having to iterate through the scoreboard looking for our slot
110
ScoreboardSlot* Scoreboard::findScoreboardSlotToLog(Session *session) 
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
2318.8.8 by Olaf van der Spek
Refactor Scoreboard
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; 
1561.3.20 by Joe Daly
add a index in session.h this will allow repeated lookups without having to iterate through the scoreboard looking for our slot
140
  }
141
2318.8.8 by Olaf van der Spek
Refactor Scoreboard
142
  LOCK_scoreboard_vector->unlock(); 
143
1561.3.20 by Joe Daly
add a index in session.h this will allow repeated lookups without having to iterate through the scoreboard looking for our slot
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
1561.3.2 by Joe Daly
add session_status_new
149
ScoreboardSlot* Scoreboard::findOurScoreboardSlot(Session *session)
1491.4.24 by Joe Daly
remove scoreboard index from Session class
150
{
1561.3.20 by Joe Daly
add a index in session.h this will allow repeated lookups without having to iterate through the scoreboard looking for our slot
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;
2318.8.8 by Olaf van der Spek
Refactor Scoreboard
155
  return vector_of_scoreboard_vectors.at(getBucketNumber(session))->at(session_scoreboard_slot);
1320.5.6 by Joe Daly
first pass at using a module vector approach of scoreboard
156
}