NdbPoolImpl.hpp
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:6k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2003 MySQL AB
  2.    This program is free software; you can redistribute it and/or modify
  3.    it under the terms of the GNU General Public License as published by
  4.    the Free Software Foundation; either version 2 of the License, or
  5.    (at your option) any later version.
  6.    This program is distributed in the hope that it will be useful,
  7.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  8.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9.    GNU General Public License for more details.
  10.    You should have received a copy of the GNU General Public License
  11.    along with this program; if not, write to the Free Software
  12.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  13. /**
  14.   @section ndbPool              Pooling of NDB objects
  15.   This class implements pooling of NDB objects to support MySQL, ODBC and
  16.   any application with a great number of threads.
  17.   The general idea is to let the NdbPool class administer all Ndb objects.
  18.   When a thread needs a Ndb object it request a Ndb object from the Pool.
  19.   This interface contains some hints to ensure that the proper Ndb object
  20.   is returned.
  21.   The object contains an array of references to all Ndb objects together with
  22.   an indication of whether the object is free or not.
  23.   The idea is that the thread should keep track of the Ndb object it used the
  24.   last time. If this object is still free it will simply get this object
  25.   back. If the number of threads do not exceed the number of Ndb objects this
  26.   will always be successful. In certain situations the number of threads will
  27.   be much greater than the number of Ndb objects. In this situation the Pool
  28.   will attempt to provide an object that is attached to the same schema
  29.   as the thread is connected to. If this is not possible it will attempt to
  30.   get any free Ndb object. If not even this is possible the Pool will wait
  31.   until an Ndb object becomes free. If an Ndb object becomes available in
  32.   time it will deliver this Ndb object. In the worst case the call will
  33.   time-out and return NULL to indicate no free Ndb object was found in time.
  34.   The implementation uses an array of structs which contain a reference to a
  35.   Ndb object, whether it is in use currently and a number of references to
  36.   set up linked lists of
  37.   1) Free objects on a schema
  38.   2) Free objects in LIFO order
  39.   Usage:
  40.   The class is a singleton.
  41.   The first step is to call create_instance(..). If successful this will
  42.   create the NdbPool object and return a reference to it. When completed
  43.   drop_instance is called to remove the NdbPool object and all memory and
  44.   other resources attached to it.
  45.   After initialising the NdbPool object all threads can now start using the
  46.   NdbPool. There are two methods in normal usage mode. The first
  47.   get_ndb_object gets a Ndb object and the second return_ndb_object returns
  48.   an Ndb object. The user of the NdbPool must keep track of the identity
  49.   of the Ndb object. The idea is that this identity can also be used to
  50.   find the object quickly again unless another thread have taken it. If the
  51.   user wants any Ndb object it requests identity 0 which means any here.
  52.   When constructing the NdbPool one can set the number of NdbConnection
  53.   objects which are allowed in all Ndb objects. For use in synchronous
  54.   applications such as the MySQL server 4 objects should be enough. When
  55.   using the NdbPool for asynchronous applications one should use 1024 to
  56.   enable a high level of parallelism. It is also possible to set the
  57.   maximum number of Ndb objects in the pool and the initial number of
  58.   Ndb objects allocated.
  59. */
  60. #ifndef NdbPool_H
  61. #define NdbPool_H
  62. #include <Ndb.hpp>
  63. #include <NdbMutex.h>
  64. #include <NdbCondition.h>
  65. #include <NdbOut.hpp>
  66. class NdbPool {
  67. #define NULL_POOL 0
  68. #define NULL_HASH 0xFF
  69. #define POOL_HASH_TABLE_SIZE 32
  70. #define MAX_NDB_OBJECTS 240
  71.   struct POOL_STRUCT {
  72.     Ndb* ndb_reference;
  73.     bool in_use;
  74.     bool free_entry;
  75.     Uint16 next_free_object;
  76.     Uint16 prev_free_object;
  77.     Uint16 next_db_object;
  78.     Uint16 prev_db_object;
  79.   };
  80.   public:
  81.     static NdbPool* create_instance(Uint32 max_ndb_objects = 240,
  82.                                     Uint32 no_conn_obj = 4,
  83.                                     Uint32 init_no_ndb_objects = 8);
  84.     static void drop_instance();
  85.     Ndb* get_ndb_object(Uint32 &hint_id,
  86.                         const char* a_catalog_name,
  87.                         const char* a_schema_name);
  88.     void return_ndb_object(Ndb* returned_object, Uint32 id);
  89.   private:
  90.     bool init(Uint32 initial_no_of_ndb_objects = 8);
  91.     void release_all();
  92.     static bool initPoolMutex();
  93.     NdbPool(Uint32 max_no_of_ndb_objects, Uint32 no_conn_objects);
  94.     ~NdbPool();
  95.   /*
  96.   We have three lists:
  97.   1) A list for entries not in use
  98.   2) A list for free entries
  99.   3) A hash table with schema name and database name as key
  100.   These lists are all initialised in the init call.
  101.   The list for entries not in use is very simple since the current
  102.   implementation have not yet any handling of dropping Ndb objects
  103.   until all Ndb objects are dropped.
  104.   */
  105.     void add_free_list(Uint32 id);
  106.     void remove_free_list(Uint32 id);
  107.     Ndb* get_free_list(Uint32 &id, Uint32 hash_entry);
  108.     void add_db_hash(Uint32 id);
  109.     void remove_db_hash(Uint32 id, Uint32 hash_entry);
  110.     Ndb* get_db_hash(Uint32 &id,
  111.                      Uint32 hash_entry,
  112.                      const char* a_catalog_name,
  113.                      const char* a_schema_name);
  114.     bool allocate_ndb(Uint32 &id,
  115.                       const char* a_catalog_name,
  116.                       const char* a_schema_name);
  117.     Ndb* get_hint_ndb(Uint32 id, Uint32 hash_entry);
  118.     Ndb* wait_free_ndb(Uint32 &id);
  119.     Uint32 compute_hash(const char *a_schema_name);
  120.     void add_wait_list(Uint32 id);
  121.     void remove_wait_list();
  122.     void switch_condition_queue();
  123.     static NdbMutex     *pool_mutex;
  124.     struct NdbCondition *input_pool_cond;
  125.     struct NdbCondition *output_pool_cond;
  126.     POOL_STRUCT *m_pool_reference;
  127.     Uint8       *m_hash_entry;
  128.     bool        m_inited;
  129.     Uint32      m_no_of_conn_objects;
  130.     Uint16      m_no_of_objects;
  131.     Uint16      m_max_ndb_objects;
  132.     Uint16      m_first_free;
  133.     Uint16      m_last_free;
  134.     Uint16      m_first_not_in_use;
  135.     Uint16      m_waiting;
  136.     Uint16      m_first_wait;
  137.     Uint16      m_input_queue;
  138.     Uint16      m_output_queue;
  139.     Uint16      m_signal_count;
  140. };
  141. #endif