mirror of
https://github.com/MariaDB/server.git
synced 2025-11-24 06:01:25 +03:00
Initial revision of NDB Cluster files
BitKeeper/etc/logging_ok: Logging to logging@openlogging.org accepted
This commit is contained in:
162
ndb/src/ndbapi/NdbPoolImpl.hpp
Normal file
162
ndb/src/ndbapi/NdbPoolImpl.hpp
Normal file
@@ -0,0 +1,162 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
/**
|
||||
@section ndbPool Pooling of NDB objects
|
||||
This class implements pooling of NDB objects to support MySQL, ODBC and
|
||||
any application with a great number of threads.
|
||||
|
||||
The general idea is to let the NdbPool class administer all Ndb objects.
|
||||
When a thread needs a Ndb object it request a Ndb object from the Pool.
|
||||
This interface contains some hints to ensure that the proper Ndb object
|
||||
is returned.
|
||||
|
||||
The object contains an array of references to all Ndb objects together with
|
||||
an indication of whether the object is free or not.
|
||||
|
||||
The idea is that the thread should keep track of the Ndb object it used the
|
||||
last time. If this object is still free it will simply get this object
|
||||
back. If the number of threads do not exceed the number of Ndb objects this
|
||||
will always be successful. In certain situations the number of threads will
|
||||
be much greater than the number of Ndb objects. In this situation the Pool
|
||||
will attempt to provide an object that is attached to the same schema
|
||||
as the thread is connected to. If this is not possible it will attempt to
|
||||
get any free Ndb object. If not even this is possible the Pool will wait
|
||||
until an Ndb object becomes free. If an Ndb object becomes available in
|
||||
time it will deliver this Ndb object. In the worst case the call will
|
||||
time-out and return NULL to indicate no free Ndb object was found in time.
|
||||
|
||||
The implementation uses an array of structs which contain a reference to a
|
||||
Ndb object, whether it is in use currently and a number of references to
|
||||
set up linked lists of
|
||||
1) Free objects on a schema
|
||||
2) Free objects in LIFO order
|
||||
|
||||
Usage:
|
||||
The class is a singleton.
|
||||
The first step is to call create_instance(..). If successful this will
|
||||
create the NdbPool object and return a reference to it. When completed
|
||||
drop_instance is called to remove the NdbPool object and all memory and
|
||||
other resources attached to it.
|
||||
|
||||
After initialising the NdbPool object all threads can now start using the
|
||||
NdbPool. There are two methods in normal usage mode. The first
|
||||
get_ndb_object gets a Ndb object and the second return_ndb_object returns
|
||||
an Ndb object. The user of the NdbPool must keep track of the identity
|
||||
of the Ndb object. The idea is that this identity can also be used to
|
||||
find the object quickly again unless another thread have taken it. If the
|
||||
user wants any Ndb object it requests identity 0 which means any here.
|
||||
|
||||
When constructing the NdbPool one can set the number of NdbConnection
|
||||
objects which are allowed in all Ndb objects. For use in synchronous
|
||||
applications such as the MySQL server 4 objects should be enough. When
|
||||
using the NdbPool for asynchronous applications one should use 1024 to
|
||||
enable a high level of parallelism. It is also possible to set the
|
||||
maximum number of Ndb objects in the pool and the initial number of
|
||||
Ndb objects allocated.
|
||||
*/
|
||||
|
||||
#ifndef NdbPool_H
|
||||
#define NdbPool_H
|
||||
|
||||
#include <Ndb.hpp>
|
||||
#include <NdbMutex.h>
|
||||
#include <NdbCondition.h>
|
||||
#include <NdbOut.hpp>
|
||||
|
||||
class NdbPool {
|
||||
#define NULL_POOL 0
|
||||
#define NULL_HASH 0xFF
|
||||
#define POOL_HASH_TABLE_SIZE 32
|
||||
#define MAX_NDB_OBJECTS 240
|
||||
struct POOL_STRUCT {
|
||||
Ndb* ndb_reference;
|
||||
bool in_use;
|
||||
bool free_entry;
|
||||
Uint16 next_free_object;
|
||||
Uint16 prev_free_object;
|
||||
Uint16 next_db_object;
|
||||
Uint16 prev_db_object;
|
||||
};
|
||||
public:
|
||||
static NdbPool* create_instance(Uint32 max_ndb_objects = 240,
|
||||
Uint32 no_conn_obj = 4,
|
||||
Uint32 init_no_ndb_objects = 8);
|
||||
static void drop_instance();
|
||||
Ndb* get_ndb_object(Uint32 &hint_id,
|
||||
const char* a_catalog_name,
|
||||
const char* a_schema_name);
|
||||
void return_ndb_object(Ndb* returned_object, Uint32 id);
|
||||
private:
|
||||
bool init(Uint32 initial_no_of_ndb_objects = 8);
|
||||
void release_all();
|
||||
static bool initPoolMutex();
|
||||
NdbPool(Uint32 max_no_of_ndb_objects, Uint32 no_conn_objects);
|
||||
~NdbPool();
|
||||
/*
|
||||
We have three lists:
|
||||
1) A list for entries not in use
|
||||
2) A list for free entries
|
||||
3) A hash table with schema name and database name as key
|
||||
|
||||
These lists are all initialised in the init call.
|
||||
The list for entries not in use is very simple since the current
|
||||
implementation have not yet any handling of dropping Ndb objects
|
||||
until all Ndb objects are dropped.
|
||||
*/
|
||||
void add_free_list(Uint32 id);
|
||||
void remove_free_list(Uint32 id);
|
||||
Ndb* get_free_list(Uint32 &id, Uint32 hash_entry);
|
||||
|
||||
void add_db_hash(Uint32 id);
|
||||
void remove_db_hash(Uint32 id, Uint32 hash_entry);
|
||||
Ndb* get_db_hash(Uint32 &id,
|
||||
Uint32 hash_entry,
|
||||
const char* a_catalog_name,
|
||||
const char* a_schema_name);
|
||||
|
||||
bool allocate_ndb(Uint32 &id,
|
||||
const char* a_catalog_name,
|
||||
const char* a_schema_name);
|
||||
Ndb* get_hint_ndb(Uint32 id, Uint32 hash_entry);
|
||||
Ndb* wait_free_ndb(Uint32 &id);
|
||||
Uint32 compute_hash(const char *a_schema_name);
|
||||
void add_wait_list(Uint32 id);
|
||||
void remove_wait_list();
|
||||
void switch_condition_queue();
|
||||
|
||||
static NdbMutex *pool_mutex;
|
||||
struct NdbCondition *input_pool_cond;
|
||||
struct NdbCondition *output_pool_cond;
|
||||
|
||||
POOL_STRUCT *m_pool_reference;
|
||||
Uint8 *m_hash_entry;
|
||||
|
||||
bool m_inited;
|
||||
Uint32 m_no_of_conn_objects;
|
||||
|
||||
Uint16 m_no_of_objects;
|
||||
Uint16 m_max_ndb_objects;
|
||||
Uint16 m_first_free;
|
||||
Uint16 m_last_free;
|
||||
Uint16 m_first_not_in_use;
|
||||
Uint16 m_waiting;
|
||||
Uint16 m_first_wait;
|
||||
Uint16 m_input_queue;
|
||||
Uint16 m_output_queue;
|
||||
Uint16 m_signal_count;
|
||||
};
|
||||
#endif
|
||||
Reference in New Issue
Block a user