List:Internals« Previous MessageNext Message »
From:jonas Date:September 16 2005 9:26am
Subject:bk commit into 4.1 tree (jonas:1.2422)
View as plain text  
Below is the list of changes that have just been committed into a local
4.1 repository of jonas. When jonas does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet
  1.2422 05/09/16 11:26:34 jonas@eel.(none) +18 -0
  ndb
    impl support for querying resource usage in ndb api
    to help track down mem leaks

  ndb/tools/restore/Restore.cpp
    1.24 05/09/16 11:26:31 jonas@eel.(none) +1 -1
    Impl. reporting of free list usage
    Put free list into handler class

  ndb/src/ndbapi/Ndblist.cpp
    1.13 05/09/16 11:26:31 jonas@eel.(none) +139 -382
    Impl. reporting of free list usage
    Put free list into handler class

  ndb/src/ndbapi/Ndbinit.cpp
    1.28 05/09/16 11:26:31 jonas@eel.(none) +0 -39
    Impl. reporting of free list usage
    Put free list into handler class

  ndb/src/ndbapi/Ndbif.cpp
    1.26 05/09/16 11:26:31 jonas@eel.(none) +0 -9
    Impl. reporting of free list usage
    Put free list into handler class

  ndb/src/ndbapi/NdbUtil.hpp
    1.5 05/09/16 11:26:31 jonas@eel.(none) +23 -17
    Impl. reporting of free list usage
    Put free list into handler class

  ndb/src/ndbapi/NdbUtil.cpp
    1.2 05/09/16 11:26:31 jonas@eel.(none) +6 -10
    Impl. reporting of free list usage
    Put free list into handler class

  ndb/src/ndbapi/NdbRecAttr.cpp
    1.14 05/09/16 11:26:31 jonas@eel.(none) +2 -2
    Impl. reporting of free list usage
    Put free list into handler class

  ndb/src/ndbapi/NdbImpl.hpp
    1.7 05/09/16 11:26:31 jonas@eel.(none) +119 -0
    Impl. reporting of free list usage
    Put free list into handler class

  ndb/src/ndbapi/NdbBlob.cpp
    1.19 05/09/16 11:26:31 jonas@eel.(none) +1 -1
    Impl. reporting of free list usage
    Put free list into handler class

  ndb/src/ndbapi/NdbApiSignal.hpp
    1.4 05/09/16 11:26:31 jonas@eel.(none) +2 -1
    Impl. reporting of free list usage
    Put free list into handler class

  ndb/src/ndbapi/NdbApiSignal.cpp
    1.8 05/09/16 11:26:31 jonas@eel.(none) +19 -0
    Impl. reporting of free list usage
    Put free list into handler class

  ndb/include/ndbapi/NdbRecAttr.hpp
    1.9 05/09/16 11:26:31 jonas@eel.(none) +5 -2
    Impl. reporting of free list usage
    Put free list into handler class

  ndb/include/ndbapi/NdbOperation.hpp
    1.19 05/09/16 11:26:31 jonas@eel.(none) +5 -3
    Impl. reporting of free list usage
    Put free list into handler class

  ndb/include/ndbapi/NdbIndexScanOperation.hpp
    1.8 05/09/16 11:26:31 jonas@eel.(none) +2 -0
    Impl. reporting of free list usage
    Put free list into handler class

  ndb/include/ndbapi/NdbIndexOperation.hpp
    1.7 05/09/16 11:26:31 jonas@eel.(none) +1 -0
    Impl. reporting of free list usage
    Put free list into handler class

  ndb/include/ndbapi/NdbConnection.hpp
    1.25 05/09/16 11:26:30 jonas@eel.(none) +6 -6
    Impl. reporting of free list usage
    Put free list into handler class

  ndb/include/ndbapi/NdbBlob.hpp
    1.10 05/09/16 11:26:30 jonas@eel.(none) +5 -1
    Impl. reporting of free list usage
    Put free list into handler class

  ndb/include/ndbapi/Ndb.hpp
    1.18 05/09/16 11:26:30 jonas@eel.(none) +13 -15
    Impl. reporting of free list usage
    Put free list into handler class

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	jonas
# Host:	eel.(none)
# Root:	/home/jonas/src/mysql-4.1

--- 1.7/ndb/include/ndbapi/NdbIndexScanOperation.hpp	2004-11-22 14:41:43 +01:00
+++ 1.8/ndb/include/ndbapi/NdbIndexScanOperation.hpp	2005-09-16 11:26:31 +02:00
@@ -132,6 +132,8 @@
   int compare(Uint32 key, Uint32 cols, const NdbReceiver*, const NdbReceiver*);
 
   Uint32 m_sort_columns;
+
+  friend struct Ndb_free_list_t<NdbIndexScanOperation>;
 };
 
 #endif

--- 1.17/ndb/include/ndbapi/Ndb.hpp	2004-12-20 12:36:03 +01:00
+++ 1.18/ndb/include/ndbapi/Ndb.hpp	2005-09-16 11:26:30 +02:00
@@ -882,10 +882,10 @@
 class NdbEventOperation;
 class NdbBlob;
 class NdbReceiver;
+template <class T> struct Ndb_free_list_t;
 
 typedef void (* NdbEventCallback)(NdbEventOperation*, Ndb*, void*);
 
-
 #if defined NDB_OSE
 /**
  * Default time to wait for response after request has been sent to 
@@ -1386,8 +1386,20 @@
    */
   NdbConnection* hupp( NdbConnection* );
   Uint32 getReference() const { return theMyRef;}
+
+  struct Free_list_usage
+  {
+    const char * m_name;
+    Uint32 m_created;
+    Uint32 m_free;
+    Uint32 m_sizeof;
+  };
+
+  Free_list_usage * get_free_list_usage(Free_list_usage*);
 #endif
 
+  
+
 /*****************************************************************************
  *	These are service routines used by the other classes in the NDBAPI.
  ****************************************************************************/
@@ -1562,22 +1574,8 @@
   class NdbDictionaryImpl* theDictionary;
   class NdbGlobalEventBufferHandle* theGlobalEventBufferHandle;
 
-  NdbConnection*	theConIdleList;	// First connection in idle list.
-
-  NdbOperation*		theOpIdleList;	// First operation in the idle list. 
-
-  NdbIndexScanOperation* theScanOpIdleList;	// First scan operation in the idle list. 
-  NdbIndexOperation*	theIndexOpIdleList;	// First index operation in the idle list. 
   NdbConnection*	theTransactionList;
   NdbConnection**       theConnectionArray;
-  NdbRecAttr*		theRecAttrIdleList;  
-  NdbApiSignal*		theSignalIdleList;   // First signal in idlelist.
-  NdbLabel*		theLabelList;	     // First label descriptor in list
-  NdbBranch*		theBranchList;	     // First branch descriptor in list
-  NdbSubroutine*	theSubroutineList;   // First subroutine descriptor in
-  NdbCall*		theCallList;	     // First call descriptor in list
-  NdbReceiver*      theScanList;
-  NdbBlob*              theNdbBlobIdleList;
 
   Uint32   theMyRef;        // My block reference  
   Uint32   theNode;         // The node number of our node

--- 1.24/ndb/include/ndbapi/NdbConnection.hpp	2005-04-05 13:00:33 +02:00
+++ 1.25/ndb/include/ndbapi/NdbConnection.hpp	2005-09-16 11:26:30 +02:00
@@ -18,8 +18,9 @@
 #define NdbConnection_H
 
 #include <ndb_types.h>
-#include <NdbError.hpp>
-#include <NdbDictionary.hpp>
+#include "NdbError.hpp"
+#include "NdbDictionary.hpp"
+#include "Ndb.hpp"
 
 class NdbConnection;
 class NdbOperation;
@@ -465,10 +466,10 @@
   /**************************************************************************
    *	These are the create and delete methods of this class.              *
    **************************************************************************/
-  
   NdbConnection(Ndb* aNdb); 
-  
   ~NdbConnection();
+  NdbConnection* next();			  // Returns the next pointer
+  void next(NdbConnection*);		  // Sets the next pointer
 
   void init();           // Initialize connection object for new transaction
 
@@ -487,8 +488,6 @@
   int		getTC_ConnectPtr();		  // Gets TC Connect pointer
   void          setBuddyConPtr(Uint32);           // Sets Buddy Con Ptr
   Uint32        getBuddyConPtr();                 // Gets Buddy Con Ptr
-  NdbConnection* next();			  // Returns the next pointer
-  void		next(NdbConnection*);		  // Sets the next pointer
 
   enum ConStatusType { 
     NotConnected,
@@ -691,6 +690,7 @@
   void define_scan_op(NdbIndexScanOperation*);
 
   friend class HugoOperations;
+  friend struct Ndb_free_list_t<NdbConnection>;
 };
 
 inline

--- 1.6/ndb/include/ndbapi/NdbIndexOperation.hpp	2004-10-31 15:21:50 +01:00
+++ 1.7/ndb/include/ndbapi/NdbIndexOperation.hpp	2005-09-16 11:26:31 +02:00
@@ -200,6 +200,7 @@
   Uint32 m_theIndexDefined[NDB_MAX_ATTRIBUTES_IN_INDEX][3];
   Uint32 m_theIndexLen;	  	 // Length of the index in words
   Uint32 m_theNoOfIndexDefined;  // The number of index attributes
+  friend struct Ndb_free_list_t<NdbIndexOperation>;
 };
 
 #endif

--- 1.18/ndb/include/ndbapi/NdbOperation.hpp	2004-10-31 15:21:50 +01:00
+++ 1.19/ndb/include/ndbapi/NdbOperation.hpp	2005-09-16 11:26:31 +02:00
@@ -22,6 +22,7 @@
 #include "NdbError.hpp"
 #include "NdbReceiver.hpp"
 #include "NdbDictionary.hpp"
+#include "Ndb.hpp"
 
 class Ndb;
 class NdbApiSignal;
@@ -723,8 +724,6 @@
 /******************************************************************************
  * These are the methods used to create and delete the NdbOperation objects.
  *****************************************************************************/
-  			NdbOperation(Ndb* aNdb);	
-  			virtual ~NdbOperation();
 
   bool                  needReply();
 /******************************************************************************
@@ -736,8 +735,9 @@
   int init(const class NdbTableImpl*, NdbConnection* aCon);
   void initInterpreter();
 
+  NdbOperation(Ndb* aNdb);	
+  virtual ~NdbOperation();
   void	next(NdbOperation*);		// Set next pointer		      
-
   NdbOperation*	    next();	        // Get next pointer		       
 
   enum OperationStatus{ 
@@ -925,6 +925,8 @@
    * IgnoreError on connection level.
    */
   Int8 m_abortOption;
+
+  friend struct Ndb_free_list_t<NdbOperation>;
 };
 
 #ifdef NDB_NO_DROPPED_SIGNAL

--- 1.8/ndb/include/ndbapi/NdbRecAttr.hpp	2005-01-24 10:33:32 +01:00
+++ 1.9/ndb/include/ndbapi/NdbRecAttr.hpp	2005-09-16 11:26:31 +02:00
@@ -17,7 +17,8 @@
 #ifndef NdbRecAttr_H
 #define NdbRecAttr_H
 
-#include <NdbDictionary.hpp>
+#include "NdbDictionary.hpp"
+#include "Ndb.hpp"
 
 class NdbOperation;
 
@@ -242,7 +243,6 @@
    */
   ~NdbRecAttr();    
 private:
-  NdbRecAttr();
 
   Uint32 attrId() const;        /* Get attribute id                     */
   bool setNULL();               /* Set NULL indicator                   */
@@ -251,6 +251,7 @@
   void release();               /* Release memory if allocated          */
   void init();                  /* Initialise object when allocated     */
 
+  NdbRecAttr(Ndb*);
   void next(NdbRecAttr* aRecAttr);
   NdbRecAttr* next() const;
 
@@ -273,6 +274,8 @@
   Uint32 theAttrSize;
   Uint32 theArraySize;
   const NdbDictionary::Column* m_column;
+
+  friend struct Ndb_free_list_t<NdbRecAttr>;
 };
 
 inline

--- 1.23/ndb/tools/restore/Restore.cpp	2005-06-08 16:48:54 +02:00
+++ 1.24/ndb/tools/restore/Restore.cpp	2005-09-16 11:26:31 +02:00
@@ -869,7 +869,7 @@
     return ndbout;
   }
   
-  NdbRecAttr tmprec;
+  NdbRecAttr tmprec(0);
   tmprec.setup(desc.m_column, (char *)data.void_value);
   ndbout << tmprec;
 

--- 1.7/ndb/src/ndbapi/NdbApiSignal.cpp	2004-10-08 09:43:35 +02:00
+++ 1.8/ndb/src/ndbapi/NdbApiSignal.cpp	2005-09-16 11:26:31 +02:00
@@ -62,6 +62,25 @@
   theNextSignal = 0;
 }
 
+NdbApiSignal::NdbApiSignal(Ndb* ndb)
+{
+  BlockReference ref = ndb->theMyRef;
+  theVerId_signalNumber   = 0;    // 4 bit ver id - 16 bit gsn
+  theReceiversBlockNumber = 0;  // Only 16 bit blocknum  
+  theSendersBlockRef      = refToBlock(ref);
+  theLength               = 0;
+  theSendersSignalId      = 0;
+  theSignalId             = 0;
+  theTrace                = 0;
+  m_noOfSections          = 0;
+  m_fragmentInfo          = 0;
+  for (int i = 0; i < 25; i++)
+    theData[i] = 0x13579753;
+  
+  setDataPtr(&theData[0]);
+  theNextSignal = 0;
+}
+
 /**
  * Copy constructor
  */

--- 1.3/ndb/src/ndbapi/NdbApiSignal.hpp	2004-08-09 17:43:08 +02:00
+++ 1.4/ndb/src/ndbapi/NdbApiSignal.hpp	2005-09-16 11:26:31 +02:00
@@ -46,7 +46,8 @@
 class NdbApiSignal : public SignalHeader
  {
 public:  
-  			NdbApiSignal(BlockReference myRef);
+  			NdbApiSignal(Ndb* ndb);
+  			NdbApiSignal(BlockReference ref);
   			NdbApiSignal(const NdbApiSignal &);
                         NdbApiSignal(const SignalHeader &header)
 			  : SignalHeader(header), theNextSignal(0), theRealData(0) {};

--- 1.6/ndb/src/ndbapi/NdbImpl.hpp	2004-12-20 12:36:03 +01:00
+++ 1.7/ndb/src/ndbapi/NdbImpl.hpp	2005-09-16 11:26:31 +02:00
@@ -32,6 +32,21 @@
 #include "NdbDictionaryImpl.hpp"
 #include "ObjectMap.hpp"
 
+template <class T>
+struct Ndb_free_list_t 
+{
+  Ndb_free_list_t();
+  ~Ndb_free_list_t();
+  
+  void fill(Ndb*, Uint32 cnt);
+  T* seize(Ndb*);
+  void release(T*);
+  void clear();
+  Uint32 get_sizeof() const { return sizeof(T); }
+  T * m_free_list;
+  Uint32 m_alloc_cnt, m_free_cnt;
+};
+
 /**
  * Private parts of the Ndb object (corresponding to Ndb.hpp in public API)
  */
@@ -59,6 +74,23 @@
   NdbWaiter             theWaiter;
 
   int m_optimized_node_selection;
+
+  /**
+   * NOTE free lists must be _after_ theNdbObjectIdMap take
+   *   assure that destructors are run in correct order
+   */
+  Ndb_free_list_t<NdbConnection> theConIdleList; 
+  Ndb_free_list_t<NdbOperation>  theOpIdleList;  
+  Ndb_free_list_t<NdbIndexScanOperation> theScanOpIdleList;
+  Ndb_free_list_t<NdbIndexOperation> theIndexOpIdleList;
+  Ndb_free_list_t<NdbRecAttr> theRecAttrIdleList;  
+  Ndb_free_list_t<NdbApiSignal> theSignalIdleList;
+  Ndb_free_list_t<NdbLabel> theLabelList;
+  Ndb_free_list_t<NdbBranch> theBranchList;
+  Ndb_free_list_t<NdbSubroutine> theSubroutineList;
+  Ndb_free_list_t<NdbCall> theCallList;
+  Ndb_free_list_t<NdbBlob> theNdbBlobIdleList;
+  Ndb_free_list_t<NdbReceiver> theScanList;
 };
 
 #ifdef VM_TRACE
@@ -132,5 +164,92 @@
   Insert,
   Delete 
 };
+
+template<class T>
+inline
+Ndb_free_list_t<T>::Ndb_free_list_t()
+{
+  m_free_list= 0; 
+  m_alloc_cnt= m_free_cnt= 0; 
+}
+
+template<class T>
+inline
+Ndb_free_list_t<T>::~Ndb_free_list_t()
+{
+  clear();
+}
+    
+template<class T>
+inline
+void
+Ndb_free_list_t<T>::fill(Ndb* ndb, Uint32 cnt)
+{
+  if (m_free_list == 0)
+  {
+    m_free_cnt++;
+    m_alloc_cnt++;
+    m_free_list = new T(ndb);
+  }
+  while(m_alloc_cnt < cnt)
+  {
+    T* obj= new T(ndb);
+    if(obj == 0)
+      return;
+    
+    obj->next(m_free_list);
+    m_free_cnt++;
+    m_alloc_cnt++;
+    m_free_list = obj;
+  }
+}
+
+template<class T>
+inline
+T*
+Ndb_free_list_t<T>::seize(Ndb* ndb)
+{
+  T* tmp = m_free_list;
+  if (tmp)
+  {
+    m_free_list = (T*)tmp->next();
+    tmp->next(NULL);
+    m_free_cnt--;
+    return tmp;
+  }
+  
+  if((tmp = new T(ndb)))
+  {
+    m_alloc_cnt++;
+  }
+  
+  return tmp;
+}
+
+template<class T>
+inline
+void
+Ndb_free_list_t<T>::release(T* obj)
+{
+  obj->next(m_free_list);
+  m_free_list = obj;
+  m_free_cnt++;
+}
+
+
+template<class T>
+inline
+void
+Ndb_free_list_t<T>::clear()
+{
+  T* obj = m_free_list;
+  while(obj)
+  {
+    T* curr = obj;
+    obj = (T*)obj->next();
+    delete curr;
+    m_alloc_cnt--;
+  }
+}
 
 #endif

--- 1.13/ndb/src/ndbapi/NdbRecAttr.cpp	2005-02-16 12:43:56 +01:00
+++ 1.14/ndb/src/ndbapi/NdbRecAttr.cpp	2005-09-16 11:26:31 +02:00
@@ -33,7 +33,7 @@
 #include "NdbDictionaryImpl.hpp"
 #include <NdbTCP.h>
 
-NdbRecAttr::NdbRecAttr()
+NdbRecAttr::NdbRecAttr(Ndb*)
 {
   init();
 }
@@ -109,7 +109,7 @@
 
 NdbRecAttr *
 NdbRecAttr::clone() const {
-  NdbRecAttr * ret = new NdbRecAttr();
+  NdbRecAttr * ret = new NdbRecAttr(0);
 
   ret->theAttrId = theAttrId;
   ret->theNULLind = theNULLind;

--- 1.1/ndb/src/ndbapi/NdbUtil.cpp	2004-04-14 10:24:25 +02:00
+++ 1.2/ndb/src/ndbapi/NdbUtil.cpp	2005-09-16 11:26:31 +02:00
@@ -30,8 +30,7 @@
 
 #include "NdbUtil.hpp"
 
-NdbLabel::NdbLabel() :
-  theNext(NULL)
+NdbLabel::NdbLabel(Ndb*)
 {
 }
 
@@ -39,8 +38,7 @@
 {
 }
 
-NdbSubroutine::NdbSubroutine() :
-  theNext(NULL)
+NdbSubroutine::NdbSubroutine(Ndb*)
 {
 }
 
@@ -48,9 +46,8 @@
 {
 }
 
-NdbBranch::NdbBranch() :
-  theSignal(NULL),
-  theNext(NULL)
+NdbBranch::NdbBranch(Ndb*) :
+  theSignal(NULL)
 {
 }
 
@@ -58,9 +55,8 @@
 {
 }
 
-NdbCall::NdbCall() :
-  theSignal(NULL),
-  theNext(NULL)
+NdbCall::NdbCall(Ndb*) :
+  theSignal(NULL)
 {
 }
 

--- 1.4/ndb/src/ndbapi/NdbUtil.hpp	2004-05-25 11:53:05 +02:00
+++ 1.5/ndb/src/ndbapi/NdbUtil.hpp	2005-09-16 11:26:31 +02:00
@@ -34,41 +34,49 @@
 class NdbApiSignal;
 class NdbOperation;
 
-class NdbLabel
+template<class T>
+struct Free_list_element 
+{
+  Free_list_element() { theNext = 0;}
+  void next(T* obj) { theNext = obj;}
+  T* next() { return theNext;}
+
+  T* theNext;
+};
+
+class NdbLabel : public Free_list_element<NdbLabel>
 {
 friend class NdbOperation;
 friend class Ndb;
-
-private:
-  NdbLabel();
+public:
+  NdbLabel(Ndb*);
   ~NdbLabel();
 
-  NdbLabel* theNext;
+private:
   Uint32   theSubroutine[16];
   Uint32   theLabelAddress[16];
   Uint32   theLabelNo[16];
 };
 
-class NdbSubroutine
+class NdbSubroutine : public Free_list_element<NdbSubroutine>
 {
 friend class NdbOperation;
 friend class Ndb;
 
-private:
-  NdbSubroutine();
+public:
+  NdbSubroutine(Ndb*);
   ~NdbSubroutine();
 
-  NdbSubroutine* theNext;
   Uint32   theSubroutineAddress[16];
 };
 
-class NdbBranch
+class NdbBranch : public Free_list_element<NdbBranch>
 {
 friend class NdbOperation;
 friend class Ndb;
 
-private:
-  NdbBranch();
+public:
+  NdbBranch(Ndb*);
   ~NdbBranch();
 
   NdbApiSignal* theSignal;
@@ -76,22 +84,20 @@
   Uint32       theBranchAddress;
   Uint32	theBranchLabel;
   Uint32	theSubroutine;
-  NdbBranch*	theNext;
 };
 
-class NdbCall
+class NdbCall : public Free_list_element<NdbCall>
 {
 friend class NdbOperation;
 friend class Ndb;
 
-private:
-  NdbCall();
+public:
+  NdbCall(Ndb*);
   ~NdbCall();
 
   NdbApiSignal* theSignal;
   Uint32       theSignalAddress;
   Uint32	theSubroutine;
-  NdbCall*	theNext;
 };
 
 #endif

--- 1.25/ndb/src/ndbapi/Ndbif.cpp	2005-04-18 12:41:09 +02:00
+++ 1.26/ndb/src/ndbapi/Ndbif.cpp	2005-09-16 11:26:31 +02:00
@@ -143,15 +143,6 @@
 error_handler:
   ndbout << "error_handler" << endl;
   releaseTransactionArrays();
-  while ( theConIdleList != NULL )
-    freeNdbCon();
-  while ( theSignalIdleList != NULL )
-    freeSignal();
-  while (theRecAttrIdleList != NULL)
-    freeRecAttr(); 
-  while (theOpIdleList != NULL)
-    freeOperation();
-  
   delete theDictionary;
   TransporterFacade::instance()->close(theNdbBlockNumber, 0);
   DBUG_RETURN(-1);

--- 1.27/ndb/src/ndbapi/Ndbinit.cpp	2004-12-22 14:58:55 +01:00
+++ 1.28/ndb/src/ndbapi/Ndbinit.cpp	2005-09-16 11:26:31 +02:00
@@ -99,20 +99,8 @@
   theMaxNoOfTransactions= 0;
   theMinNoOfEventsToWakeUp= 0;
   prefixEnd= NULL;
-  theConIdleList= NULL;
-  theOpIdleList= NULL;
-  theScanOpIdleList= NULL;
-  theIndexOpIdleList= NULL;
   theTransactionList= NULL;
   theConnectionArray= NULL;
-  theRecAttrIdleList= NULL;
-  theSignalIdleList= NULL;
-  theLabelList= NULL;
-  theBranchList= NULL;
-  theSubroutineList= NULL;
-  theCallList= NULL;
-  theScanList= NULL;
-  theNdbBlobIdleList= NULL;
   the_last_check_time= 0;
   theFirstTransId= 0;
   theRestartGCI= 0;
@@ -203,33 +191,6 @@
   if (TransporterFacade::instance() != NULL && theNdbBlockNumber > 0){
     TransporterFacade::instance()->close(theNdbBlockNumber, theFirstTransId);
   }
-  
-//  if (theSchemaConToNdbList != NULL)
-//    closeSchemaTransaction(theSchemaConToNdbList);
-  while ( theConIdleList != NULL )
-    freeNdbCon();
-  while (theOpIdleList != NULL)
-    freeOperation();
-  while (theScanOpIdleList != NULL)
-    freeScanOperation();
-  while (theIndexOpIdleList != NULL)
-    freeIndexOperation();
-  while (theLabelList != NULL)
-    freeNdbLabel();
-  while (theBranchList != NULL)
-    freeNdbBranch();
-   while (theSubroutineList != NULL)
-    freeNdbSubroutine();
-   while (theCallList != NULL)
-    freeNdbCall();
-  while (theScanList != NULL)
-    freeNdbScanRec();
-  while (theNdbBlobIdleList != NULL)
-    freeNdbBlob();
-  while (theRecAttrIdleList != NULL)
-    freeRecAttr(); 
-  while ( theSignalIdleList != NULL )
-    freeSignal();
   
   releaseTransactionArrays();
 

--- 1.12/ndb/src/ndbapi/Ndblist.cpp	2004-12-17 09:55:19 +01:00
+++ 1.13/ndb/src/ndbapi/Ndblist.cpp	2005-09-16 11:26:31 +02:00
@@ -76,25 +76,7 @@
 int 
 Ndb::createConIdleList(int aNrOfCon)
 {
-  for (int i = 0; i < aNrOfCon; i++)
-  {
-    NdbConnection* tNdbCon = new NdbConnection(this);
-    if (tNdbCon == NULL)
-    {
-      return -1;
-    }
-    if (theConIdleList == NULL)
-    {
-      theConIdleList = tNdbCon;
-      theConIdleList->next(NULL);
-    } else
-    {
-      tNdbCon->next(theConIdleList);
-      theConIdleList = tNdbCon;
-    }
-    tNdbCon->Status(NdbConnection::NotConnected);
-  }
-  theNoOfAllocatedTransactions = aNrOfCon;
+  theImpl->theConIdleList.fill(this, aNrOfCon);
   return aNrOfCon; 
 }
 
@@ -110,19 +92,7 @@
 int 
 Ndb::createOpIdleList(int aNrOfOp)
 { 
-  for (int i = 0; i < aNrOfOp; i++){
-    NdbOperation* tOp = new NdbOperation(this);
-    if ( tOp == NULL ){
-      return -1;
-    }
-    if (theOpIdleList == NULL){
-      theOpIdleList = tOp;
-      theOpIdleList->next(NULL);
-    } else{
-      tOp->next(theOpIdleList);
-      theOpIdleList = tOp;
-    }
-  }
+  theImpl->theOpIdleList.fill(this, aNrOfOp);
   return aNrOfOp; 
 }
 
@@ -136,22 +106,7 @@
 NdbBranch*
 Ndb::getNdbBranch()
 {
-  NdbBranch*    tNdbBranch;
-  if ( theBranchList == NULL )
-  {
-    tNdbBranch = new NdbBranch;
-    if (tNdbBranch == NULL)
-    {
-      return NULL;
-    }
-    tNdbBranch->theNext = NULL;
-  } else
-  {
-    tNdbBranch = theBranchList;
-    theBranchList = tNdbBranch->theNext;
-    tNdbBranch->theNext = NULL;
-  }
-  return tNdbBranch;
+  return theImpl->theBranchList.seize(this);
 }
 
 /***************************************************************************
@@ -164,22 +119,7 @@
 NdbCall*
 Ndb::getNdbCall()
 {
-  NdbCall*      tNdbCall;
-  if ( theCallList == NULL )
-  {
-    tNdbCall = new NdbCall;
-    if (tNdbCall == NULL)
-    {
-      return NULL;
-    }
-    tNdbCall->theNext = NULL;
-  } else
-  {
-    tNdbCall = theCallList;
-    theCallList = tNdbCall->theNext;
-    tNdbCall->theNext = NULL;
-  }
-  return tNdbCall;
+  return theImpl->theCallList.seize(this);
 }
 
 /***************************************************************************
@@ -192,25 +132,14 @@
 NdbConnection*
 Ndb::getNdbCon()
 {
-  NdbConnection*        tNdbCon;
-  if ( theConIdleList == NULL ) {
-    if (theNoOfAllocatedTransactions < theMaxNoOfTransactions) {
-      tNdbCon = new NdbConnection(this);
-      if (tNdbCon == NULL) {
-        return NULL;
-      }//if
-      theNoOfAllocatedTransactions++;
-    } else {
-      ndbout << "theNoOfAllocatedTransactions = " << theNoOfAllocatedTransactions << " theMaxNoOfTransactions = " << theMaxNoOfTransactions << endl;
-      return NULL;
-    }//if
-    tNdbCon->next(NULL);
-  } else
-  {
-    tNdbCon = theConIdleList;
-    theConIdleList = tNdbCon->next();
-    tNdbCon->next(NULL);
-  }
+  NdbConnection* tNdbCon = theImpl->theConIdleList.seize(this);
+  if (unlikely(theImpl->theConIdleList.m_alloc_cnt > theMaxNoOfTransactions)) 
+  {
+    theImpl->theConIdleList.release(tNdbCon);
+    ndbout << "theNoOfAllocatedTransactions = " << theNoOfAllocatedTransactions << " theMaxNoOfTransactions = " << theMaxNoOfTransactions << endl;
+    return NULL;
+  }//if
+  
   tNdbCon->theMagicNumber = 0x37412619;
   return tNdbCon;
 }
@@ -225,22 +154,7 @@
 NdbLabel*
 Ndb::getNdbLabel()
 {
-  NdbLabel*     tNdbLabel;
-  if ( theLabelList == NULL )
-  {
-    tNdbLabel = new NdbLabel;
-    if (tNdbLabel == NULL)
-    {
-      return NULL;
-    }
-    tNdbLabel->theNext = NULL;
-  } else
-  {
-    tNdbLabel = theLabelList;
-    theLabelList = tNdbLabel->theNext;
-    tNdbLabel->theNext = NULL;
-  }
-  return tNdbLabel;
+  return theImpl->theLabelList.seize(this);
 }
 
 /***************************************************************************
@@ -254,23 +168,7 @@
 NdbReceiver*
 Ndb::getNdbScanRec()
 {
-  NdbReceiver*      tNdbScanRec;
-  if ( theScanList == NULL )
-  {
-    tNdbScanRec = new NdbReceiver(this);
-    if (tNdbScanRec == NULL)
-    {
-      return NULL;
-    }
-    tNdbScanRec->next(NULL);
-  } else
-  {
-    tNdbScanRec = theScanList;
-    theScanList = tNdbScanRec->next();
-    tNdbScanRec->next(NULL);
-  }
-
-  return tNdbScanRec;
+  return theImpl->theScanList.seize(this);
 }
 
 /***************************************************************************
@@ -283,22 +181,7 @@
 NdbSubroutine*
 Ndb::getNdbSubroutine()
 {
-  NdbSubroutine*        tNdbSubroutine;
-  if ( theSubroutineList == NULL )
-  {
-    tNdbSubroutine = new NdbSubroutine;
-    if (tNdbSubroutine == NULL)
-    {
-      return NULL;
-    }
-    tNdbSubroutine->theNext = NULL;
-  } else
-  {
-    tNdbSubroutine = theSubroutineList;
-    theSubroutineList = tNdbSubroutine->theNext;
-    tNdbSubroutine->theNext = NULL;
-  }
-  return tNdbSubroutine;
+  return theImpl->theSubroutineList.seize(this);
 }
 
 /***************************************************************************
@@ -311,18 +194,7 @@
 NdbOperation*
 Ndb::getOperation()
 {
-  NdbOperation* tOp = theOpIdleList;
-  if (tOp != NULL ) {
-    NdbOperation* tOpNext = tOp->next();
-    tOp->next(NULL);
-    theOpIdleList = tOpNext;
-    return tOp;
-  } else {
-    tOp = new NdbOperation(this);
-    if (tOp != NULL)
-      tOp->next(NULL);
-  }
-  return tOp;
+  return theImpl->theOpIdleList.seize(this);
 }
 
 /***************************************************************************
@@ -335,18 +207,7 @@
 NdbIndexScanOperation*
 Ndb::getScanOperation()
 {
-  NdbIndexScanOperation* tOp = theScanOpIdleList;
-  if (tOp != NULL ) {
-    NdbIndexScanOperation* tOpNext = (NdbIndexScanOperation*)tOp->next();
-    tOp->next(NULL);
-    theScanOpIdleList = tOpNext;
-    return tOp;
-  } else {
-    tOp = new NdbIndexScanOperation(this);
-    if (tOp != NULL)
-      tOp->next(NULL);
-  }
-  return tOp;
+  return theImpl->theScanOpIdleList.seize(this);
 }
 
 /***************************************************************************
@@ -359,18 +220,7 @@
 NdbIndexOperation*
 Ndb::getIndexOperation()
 {
-  NdbIndexOperation* tOp = theIndexOpIdleList;
-  if (tOp != NULL ) {
-    NdbIndexOperation* tOpNext = (NdbIndexOperation*) tOp->next();
-    tOp->next(NULL);
-    theIndexOpIdleList = tOpNext;
-    return tOp;
-  } else {
-    tOp = new NdbIndexOperation(this);
-    if (tOp != NULL)
-      tOp->next(NULL);
-  }
-  return tOp;
+  return theImpl->theIndexOpIdleList.seize(this);
 }
 
 /***************************************************************************
@@ -382,21 +232,14 @@
 NdbRecAttr*
 Ndb::getRecAttr()
 {
-  NdbRecAttr* tRecAttr;
-  tRecAttr = theRecAttrIdleList;
-  if (tRecAttr != NULL) {
-    NdbRecAttr* tRecAttrNext = tRecAttr->next();
+  NdbRecAttr* tRecAttr = theImpl->theRecAttrIdleList.seize(this);
+  if (tRecAttr != NULL) 
+  {
     tRecAttr->init();
-    theRecAttrIdleList = tRecAttrNext;
     return tRecAttr;
-  } else {
-    tRecAttr = new NdbRecAttr;
-    if (tRecAttr == NULL)
-      return NULL;
-    tRecAttr->next(NULL);
-  }//if
-  tRecAttr->init();
-  return tRecAttr;
+  }
+
+  return NULL;
 }
 
 /***************************************************************************
@@ -408,34 +251,16 @@
 NdbApiSignal*
 Ndb::getSignal()
 {
-  NdbApiSignal* tSignal = theSignalIdleList;
-  if (tSignal != NULL){
-    NdbApiSignal* tSignalNext = tSignal->next();
-    tSignal->next(NULL);
-    theSignalIdleList = tSignalNext;
-  } else {
-    tSignal = new NdbApiSignal(theMyRef);
-#ifdef POORMANSPURIFY
-    cnewSignals++;
-#endif
-    if (tSignal != NULL)
-      tSignal->next(NULL);
-  }
-#ifdef POORMANSPURIFY
-  cgetSignals++;
-#endif
-  return tSignal;
+  return theImpl->theSignalIdleList.seize(this);
 }
 
 NdbBlob*
 Ndb::getNdbBlob()
 {
-  NdbBlob* tBlob = theNdbBlobIdleList;
-  if (tBlob != NULL) {
-    theNdbBlobIdleList = tBlob->theNext;
+  NdbBlob* tBlob = theImpl->theNdbBlobIdleList.seize(this);
+  if(tBlob)
+  {
     tBlob->init();
-  } else {
-    tBlob = new NdbBlob;
   }
   return tBlob;
 }
@@ -449,8 +274,7 @@
 void
 Ndb::releaseNdbBranch(NdbBranch* aNdbBranch)
 {
-  aNdbBranch->theNext = theBranchList;
-  theBranchList = aNdbBranch;
+  theImpl->theBranchList.release(aNdbBranch);
 }
 
 /***************************************************************************
@@ -462,8 +286,7 @@
 void
 Ndb::releaseNdbCall(NdbCall* aNdbCall)
 {
-  aNdbCall->theNext = theCallList;
-  theCallList = aNdbCall;
+  theImpl->theCallList.release(aNdbCall);
 }
 
 /***************************************************************************
@@ -475,9 +298,8 @@
 void
 Ndb::releaseNdbCon(NdbConnection* aNdbCon)
 {
-  aNdbCon->next(theConIdleList);
   aNdbCon->theMagicNumber = 0xFE11DD;
-  theConIdleList = aNdbCon;
+  theImpl->theConIdleList.release(aNdbCon);
 }
 
 /***************************************************************************
@@ -489,8 +311,7 @@
 void
 Ndb::releaseNdbLabel(NdbLabel* aNdbLabel)
 {
-  aNdbLabel->theNext = theLabelList;
-  theLabelList = aNdbLabel;
+  theImpl->theLabelList.release(aNdbLabel);
 }
 
 /***************************************************************************
@@ -502,8 +323,7 @@
 void
 Ndb::releaseNdbScanRec(NdbReceiver* aNdbScanRec)
 {
-  aNdbScanRec->next(theScanList);
-  theScanList = aNdbScanRec;
+  theImpl->theScanList.release(aNdbScanRec);
 }
 
 /***************************************************************************
@@ -515,8 +335,7 @@
 void
 Ndb::releaseNdbSubroutine(NdbSubroutine* aNdbSubroutine)
 {
-  aNdbSubroutine->theNext = theSubroutineList;
-  theSubroutineList = aNdbSubroutine;
+  theImpl->theSubroutineList.release(aNdbSubroutine);
 }
 
 /***************************************************************************
@@ -529,16 +348,14 @@
 Ndb::releaseOperation(NdbOperation* anOperation)
 {
   if(anOperation->m_tcReqGSN == GSN_TCKEYREQ){
-    anOperation->next(theOpIdleList);
     anOperation->theNdbCon = NULL;
     anOperation->theMagicNumber = 0xFE11D0;
-    theOpIdleList = anOperation;
+    theImpl->theOpIdleList.release(anOperation);
   } else {
     assert(anOperation->m_tcReqGSN == GSN_TCINDXREQ);
-    anOperation->next(theIndexOpIdleList);
     anOperation->theNdbCon = NULL;
     anOperation->theMagicNumber = 0xFE11D1;
-    theIndexOpIdleList = (NdbIndexOperation*)anOperation;
+    theImpl->theIndexOpIdleList.release((NdbIndexOperation*)anOperation);
   }
 }
 
@@ -551,10 +368,9 @@
 void
 Ndb::releaseScanOperation(NdbIndexScanOperation* aScanOperation)
 {
-  aScanOperation->next(theScanOpIdleList);
   aScanOperation->theNdbCon = NULL;
   aScanOperation->theMagicNumber = 0xFE11D2;
-  theScanOpIdleList = aScanOperation;
+  theImpl->theScanOpIdleList.release(aScanOperation);
 }
 
 /***************************************************************************
@@ -567,8 +383,7 @@
 Ndb::releaseRecAttr(NdbRecAttr* aRecAttr)
 {
   aRecAttr->release();
-  aRecAttr->next(theRecAttrIdleList);
-  theRecAttrIdleList = aRecAttr;
+  theImpl->theRecAttrIdleList.release(aRecAttr);
 }
 
 /***************************************************************************
@@ -595,8 +410,7 @@
 #ifdef POORMANSPURIFY
   creleaseSignals++;
 #endif
-  aSignal->next(theSignalIdleList);
-  theSignalIdleList = aSignal;
+  theImpl->theSignalIdleList.release(aSignal);
 }
 
 void
@@ -612,163 +426,7 @@
 void
 Ndb::releaseNdbBlob(NdbBlob* aBlob)
 {
-  aBlob->release();
-  aBlob->theNext = theNdbBlobIdleList;
-  theNdbBlobIdleList = aBlob;
-}
-
-/***************************************************************************
-void freeOperation();
-
-Remark:         Always release the first item in the free list
-***************************************************************************/
-void
-Ndb::freeOperation()
-{
-  NdbOperation* tOp = theOpIdleList;
-  theOpIdleList = theOpIdleList->next();
-  delete tOp;
-}
-
-/***************************************************************************
-void freeScanOperation();
-
-Remark:         Always release the first item in the free list
-***************************************************************************/
-void
-Ndb::freeScanOperation()
-{
-  NdbIndexScanOperation* tOp = theScanOpIdleList;
-  theScanOpIdleList = (NdbIndexScanOperation *)tOp->next();
-  delete tOp;
-}
-
-/***************************************************************************
-void freeIndexOperation();
-
-Remark:         Always release the first item in the free list
-***************************************************************************/
-void
-Ndb::freeIndexOperation()
-{
-  NdbIndexOperation* tOp = theIndexOpIdleList;
-  theIndexOpIdleList = (NdbIndexOperation *) theIndexOpIdleList->next();
-  delete tOp;
-}
-
-/***************************************************************************
-void freeNdbBranch();
-
-Remark:         Always release the first item in the free list
-***************************************************************************/
-void
-Ndb::freeNdbBranch()
-{
-  NdbBranch* tNdbBranch = theBranchList;
-  theBranchList = theBranchList->theNext;
-  delete tNdbBranch;
-}
-
-/***************************************************************************
-void freeNdbCall();
-
-Remark:         Always release the first item in the free list
-***************************************************************************/
-void
-Ndb::freeNdbCall()
-{
-  NdbCall* tNdbCall = theCallList;
-  theCallList = theCallList->theNext;
-  delete tNdbCall;
-}
-
-/***************************************************************************
-void freeNdbScanRec();
-
-Remark:         Always release the first item in the free list
-***************************************************************************/
-void
-Ndb::freeNdbScanRec()
-{
-  NdbReceiver* tNdbScanRec = theScanList;
-  theScanList = theScanList->next();
-  delete tNdbScanRec;
-}
-
-/***************************************************************************
-void freeNdbCon();
-
-Remark:         Always release the first item in the free list
-***************************************************************************/
-void
-Ndb::freeNdbCon()
-{
-  NdbConnection* tNdbCon = theConIdleList;
-  theConIdleList = theConIdleList->next();
-  delete tNdbCon;
-}
-
-/***************************************************************************
-void freeNdbLabel();
-
-Remark:         Always release the first item in the free list
-***************************************************************************/
-void
-Ndb::freeNdbLabel()
-{
-  NdbLabel* tNdbLabel = theLabelList;
-  theLabelList = theLabelList->theNext;
-  delete tNdbLabel;
-}
-
-/***************************************************************************
-void freeNdbSubroutine();
-
-Remark:         Always release the first item in the free list
-***************************************************************************/
-void
-Ndb::freeNdbSubroutine()
-{
-  NdbSubroutine* tNdbSubroutine = theSubroutineList;
-  theSubroutineList = theSubroutineList->theNext;
-  delete tNdbSubroutine;
-}
-
-/***************************************************************************
-void freeRecAttr();
-
-Remark:         Always release the first item in the free list
-***************************************************************************/
-void
-Ndb::freeRecAttr()
-{
-  NdbRecAttr* tRecAttr = theRecAttrIdleList;
-  theRecAttrIdleList = theRecAttrIdleList->next();
-  delete tRecAttr;
-}
-
-/***************************************************************************
-void freeSignal();
-
-Remark:         Delete  a signal object from the signal idlelist.
-***************************************************************************/
-void
-Ndb::freeSignal()
-{
-  NdbApiSignal* tSignal = theSignalIdleList;
-  theSignalIdleList = tSignal->next();
-  delete tSignal;
-#ifdef POORMANSPURIFY
-  cfreeSignals++;
-#endif
-}
-
-void
-Ndb::freeNdbBlob()
-{
-  NdbBlob* tBlob = theNdbBlobIdleList;
-  theNdbBlobIdleList = tBlob->theNext;
-  delete tBlob;
+  theImpl->theNdbBlobIdleList.release(aBlob);
 }
 
 /****************************************************************************
@@ -823,3 +481,102 @@
   DBUG_VOID_RETURN;
 }
 
+template<class T>
+static
+Ndb::Free_list_usage*
+update(Ndb::Free_list_usage* curr, 
+       Ndb_free_list_t<T> & list, 
+       const char * name)
+{
+  curr->m_name = name;
+  curr->m_created = list.m_alloc_cnt;
+  curr->m_free = list.m_free_cnt;
+  curr->m_sizeof = sizeof(T);
+  return curr;
+}
+
+Ndb::Free_list_usage*
+Ndb::get_free_list_usage(Ndb::Free_list_usage* curr)
+{
+  if (curr == 0)
+  {
+    return 0;
+  } 
+
+  if(curr->m_name == 0)
+  {
+    update(curr, theImpl->theConIdleList, "NdbTransaction");
+  }
+  else if(!strcmp(curr->m_name, "NdbTransaction"))
+  {
+    update(curr, theImpl->theOpIdleList, "NdbOperation");
+  }
+  else if(!strcmp(curr->m_name, "NdbOperation"))
+  {
+    update(curr, theImpl->theScanOpIdleList, "NdbIndexScanOperation");
+  }
+  else if(!strcmp(curr->m_name, "NdbIndexScanOperation"))
+  {
+    update(curr, theImpl->theIndexOpIdleList, "NdbIndexOperation");
+  }
+  else if(!strcmp(curr->m_name, "NdbIndexOperation"))
+  {
+    update(curr, theImpl->theRecAttrIdleList, "NdbRecAttr");
+  }
+  else if(!strcmp(curr->m_name, "NdbRecAttr"))
+  {
+    update(curr, theImpl->theSignalIdleList, "NdbApiSignal");
+  }
+  else if(!strcmp(curr->m_name, "NdbApiSignal"))
+  {
+    update(curr, theImpl->theLabelList, "NdbLabel");
+  }
+  else if(!strcmp(curr->m_name, "NdbLabel"))
+  {
+    update(curr, theImpl->theBranchList, "NdbBranch");
+  }
+  else if(!strcmp(curr->m_name, "NdbBranch"))
+  {
+    update(curr, theImpl->theSubroutineList, "NdbSubroutine");
+  }
+  else if(!strcmp(curr->m_name, "NdbSubroutine"))
+  {
+    update(curr, theImpl->theCallList, "NdbCall");
+  }
+  else if(!strcmp(curr->m_name, "NdbCall"))
+  {
+    update(curr, theImpl->theNdbBlobIdleList, "NdbBlob");
+  }
+  else if(!strcmp(curr->m_name, "NdbBlob"))
+  {
+    update(curr, theImpl->theScanList, "NdbReceiver");
+  }
+  else if(!strcmp(curr->m_name, "NdbReceiver"))
+  {
+    return 0;
+  }
+  else
+  {
+    update(curr, theImpl->theConIdleList, "NdbTransaction");
+  }
+
+  return curr;
+}
+
+#define TI(T) \
+ template Ndb::Free_list_usage* \
+ update(Ndb::Free_list_usage*, Ndb_free_list_t<T> &, const char * name);\
+ template struct Ndb_free_list_t<T>
+
+TI(NdbBlob);
+TI(NdbCall);
+TI(NdbLabel);
+TI(NdbBranch);
+TI(NdbSubroutine);
+TI(NdbApiSignal);
+TI(NdbRecAttr);
+TI(NdbOperation);
+TI(NdbReceiver);
+TI(NdbConnection);
+TI(NdbIndexOperation);
+TI(NdbIndexScanOperation);

--- 1.9/ndb/include/ndbapi/NdbBlob.hpp	2004-12-21 10:37:08 +01:00
+++ 1.10/ndb/include/ndbapi/NdbBlob.hpp	2005-09-16 11:26:30 +02:00
@@ -262,7 +262,7 @@
   // for keeping in lists
   NdbBlob* theNext;
   // initialization
-  NdbBlob();
+  NdbBlob(Ndb*);
   void init();
   void release();
   // classify operations
@@ -314,6 +314,10 @@
   int getOperationType() const;
   friend class NdbOut& operator<<(NdbOut&, const NdbBlob&);
 #endif
+
+  void next(NdbBlob* obj) { theNext= obj;}
+  NdbBlob* next() { return theNext;}
+  friend struct Ndb_free_list_t<NdbBlob>;
 };
 
 #endif

--- 1.18/ndb/src/ndbapi/NdbBlob.cpp	2004-12-21 10:37:08 +01:00
+++ 1.19/ndb/src/ndbapi/NdbBlob.cpp	2005-09-16 11:26:31 +02:00
@@ -137,7 +137,7 @@
 
 // initialization
 
-NdbBlob::NdbBlob()
+NdbBlob::NdbBlob(Ndb*)
 {
   init();
 }
Thread
bk commit into 4.1 tree (jonas:1.2422)jonas16 Sep