MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Defragger.hpp
1 /* Copyright (C) 2009 Sun Microsystems, Inc.
2  All rights reserved. Use is subject to license terms.
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; version 2 of the License.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; if not, write to the Free Software
15  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
16 
17 #ifndef Defragger_H
18 #define Defragger_H
19 
20 
21 /*
22  reception of fragmented signals
23  - defragments signal based on nodeid and fragmentid
24 */
25 
26 class Defragger {
27  struct DefragBuffer {
28  // Key
29  Uint32 m_fragment_id;
30  NodeId m_node_id;
31  // Data
32  UtilBuffer m_buffer;
33  DefragBuffer(NodeId nodeId, Uint32 fragId) :
34  m_fragment_id(fragId), m_node_id(nodeId) {}
35  };
36  Vector<DefragBuffer*> m_buffers;
37 
38  DefragBuffer* find_buffer(NodeId nodeId, Uint32 fragId){
39  for (size_t i = 0; i < m_buffers.size(); i++)
40  {
41  DefragBuffer* dbuf = m_buffers[i];
42  if (dbuf->m_node_id == nodeId &&
43  dbuf->m_fragment_id == fragId)
44  return dbuf;
45  }
46  return NULL;
47  }
48 
49  void erase_buffer(const DefragBuffer* dbuf){
50  for (size_t i = 0; i < m_buffers.size(); i++)
51  {
52  if (m_buffers[i] == dbuf)
53  {
54  delete dbuf;
55  m_buffers.erase(i);
56  return;
57  }
58  }
59  assert(false); // Should never be reached
60  }
61 
62 public:
63  Defragger() {};
64  ~Defragger()
65  {
66  for (size_t i = m_buffers.size(); i > 0; --i)
67  {
68  delete m_buffers[i-1]; // free the memory of the fragment
69  }
70  // m_buffers will be freed by ~Vector
71  };
72 
73  /*
74  return true when complete signal received
75  */
76 
77  bool defragment(SimpleSignal* sig) {
78 
79  if (!sig->isFragmented())
80  return true;
81 
82  Uint32 fragId = sig->getFragmentId();
83  NodeId nodeId = refToNode(sig->header.theSendersBlockRef);
84 
85  DefragBuffer* dbuf;
86  if(sig->isFirstFragment()){
87 
88  // Make sure buffer does not exist
89  if (find_buffer(nodeId, fragId))
90  abort();
91 
92  dbuf = new DefragBuffer(nodeId, fragId);
93  m_buffers.push_back(dbuf);
94 
95  } else {
96  dbuf = find_buffer(nodeId, fragId);
97  if (dbuf == NULL)
98  abort();
99  }
100  if (dbuf->m_buffer.append(sig->ptr[0].p, sig->ptr[0].sz * sizeof(Uint32)))
101  abort(); // OOM
102 
103  if (!sig->isLastFragment())
104  return false;
105 
106  // Copy defragmented data into signal...
107  int length = dbuf->m_buffer.length();
108  delete[] sig->ptr[0].p;
109  sig->ptr[0].sz = (length+3)/4;
110  sig->ptr[0].p = new Uint32[sig->ptr[0].sz];
111  memcpy(sig->ptr[0].p, dbuf->m_buffer.get_data(), length);
112 
113  // erase the buffer data
114  erase_buffer(dbuf);
115  return true;
116  }
117 
118 
119  /*
120  clear any unassembled signal buffers from node
121  */
122  void node_failed(NodeId nodeId) {
123  for (size_t i = m_buffers.size(); i > 0; --i)
124  {
125  if (m_buffers[i-1]->m_node_id == nodeId)
126  {
127  delete m_buffers[i]; // free the memory of the signal fragment
128  m_buffers.erase(i); // remove the reference from the vector.
129  }
130  }
131  }
132 
133 };
134 
135 #endif