Back to index

lightning-sunbird  0.9+nobinonly
morkSorting.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-  */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1999
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either of the GNU General Public License Version 2 or later (the "GPL"),
00026  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 #ifndef _MDB_
00039 #include "mdb.h"
00040 #endif
00041 
00042 #ifndef _MORK_
00043 #include "mork.h"
00044 #endif
00045 
00046 #ifndef _MORKNODE_
00047 #include "morkNode.h"
00048 #endif
00049 
00050 #ifndef _MORKMAP_
00051 #include "morkMap.h"
00052 #endif
00053 
00054 #ifndef _MORKENV_
00055 #include "morkEnv.h"
00056 #endif
00057 
00058 #ifndef _MORKTABLE_
00059 #include "morkTable.h"
00060 #endif
00061 
00062 #ifndef _MORKSTORE_
00063 #include "morkStore.h"
00064 #endif
00065 
00066 #ifndef _MORKROWSPACE_
00067 #include "morkRowSpace.h"
00068 #endif
00069 
00070 #ifndef _MORKARRAY_
00071 #include "morkArray.h"
00072 #endif
00073 
00074 #ifndef _MORKROW_
00075 #include "morkRow.h"
00076 #endif
00077 
00078 #ifndef _ORKINSORTING_
00079 #include "orkinSorting.h"
00080 #endif
00081 
00082 #ifndef _MORKTABLEROWCURSOR_
00083 #include "morkTableRowCursor.h"
00084 #endif
00085 
00086 #ifndef _MORKSORTING_
00087 #include "morkSorting.h"
00088 #endif
00089 
00090 #ifndef _MORKQUICKSORT_
00091 #include "morkQuickSort.h"
00092 #endif
00093 
00094 //3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
00095 
00096 // ````` ````` ````` ````` ````` 
00097 // { ===== begin morkNode interface =====
00098 
00099 /*public virtual*/ void
00100 morkSorting::CloseMorkNode(morkEnv* ev) /*i*/ // CloseSorting() only if open
00101 {
00102   if ( this->IsOpenNode() )
00103   {
00104     this->MarkClosing();
00105     this->CloseSorting(ev);
00106     this->MarkShut();
00107   }
00108 }
00109 
00110 /*public virtual*/
00111 morkSorting::~morkSorting() /*i*/ // assert CloseSorting() executed earlier
00112 {
00113   MORK_ASSERT(this->IsShutNode());
00114   MORK_ASSERT(mSorting_Table==0);
00115 }
00116 
00117 #define morkSorting_kExtraSlots 2 /* space for two more rows */
00118 
00119 /*public non-poly*/
00120 morkSorting::morkSorting(morkEnv* ev, const morkUsage& inUsage,
00121     nsIMdbHeap* ioNodeHeap, morkTable* ioTable,
00122     nsIMdbCompare* ioCompare,
00123     nsIMdbHeap* ioSlotHeap, mork_column inCol)
00124 : morkObject(ev, inUsage, ioNodeHeap, morkColor_kNone, (morkHandle*) 0)
00125 , mSorting_Table( 0 )
00126 
00127 , mSorting_Compare( 0 )
00128 
00129 , mSorting_RowArray(ev, morkUsage::kMember, (nsIMdbHeap*) 0,
00130   ioTable->GetRowCount() + morkSorting_kExtraSlots, ioSlotHeap)
00131   
00132 , mSorting_Col( inCol )
00133 {  
00134   if ( ev->Good() )
00135   {
00136     if ( ioTable && ioSlotHeap && ioCompare )
00137     {
00138       if ( inCol )
00139       {
00140         nsIMdbCompare_SlotStrongCompare(ioCompare, ev, &mSorting_Compare);
00141         morkTable::SlotWeakTable(ioTable, ev, &mSorting_Table);
00142         if ( ev->Good() )
00143         {
00144           mNode_Derived = morkDerived_kSorting;
00145         }
00146       }
00147       else
00148         this->ZeroColError(ev);
00149     }
00150     else
00151       ev->NilPointerError();
00152   }
00153 }
00154 
00155 /*public non-poly*/ void
00156 morkSorting::CloseSorting(morkEnv* ev) /*i*/ // called by CloseMorkNode();
00157 {
00158   if ( this )
00159   {
00160     if ( this->IsNode() )
00161     {
00162       nsIMdbCompare_SlotStrongCompare((nsIMdbCompare*) 0, ev,
00163         &mSorting_Compare);
00164       morkTable::SlotWeakTable((morkTable*) 0, ev, &mSorting_Table);
00165       mSorting_RowArray.CloseMorkNode(ev);
00166       mSorting_Col = 0;
00167       this->MarkShut();
00168     }
00169     else
00170       this->NonNodeError(ev);
00171   }
00172   else
00173     ev->NilPointerError();
00174 }
00175 
00176 // } ===== end morkNode methods =====
00177 // ````` ````` ````` ````` ````` 
00178 
00179 /*static*/ void
00180 morkSorting::NonSortingTypeError(morkEnv* ev)
00181 {
00182   ev->NewError("non morkSorting");
00183 }
00184 
00185 /*static*/ void
00186 morkSorting::NonSortingTypeWarning(morkEnv* ev)
00187 {
00188   ev->NewWarning("non morkSorting");
00189 }
00190 
00191 /*static*/ void
00192 morkSorting::NilTableError(morkEnv* ev)
00193 {
00194   ev->NewError("nil mSorting_Table");
00195 }
00196 
00197 /*static*/ void
00198 morkSorting::NilCompareError(morkEnv* ev)
00199 {
00200   ev->NewError("nil mSorting_Compare");
00201 }
00202 
00203 /*static*/ void
00204 morkSorting::ZeroColError(morkEnv* ev)
00205 {
00206   ev->NewError("zero mSorting_Col");
00207 }
00208 
00209 nsIMdbSorting*
00210 morkSorting::AcquireSortingHandle(morkEnv* ev)
00211 {
00212   nsIMdbSorting* outSorting = 0;
00213   orkinSorting* s = (orkinSorting*) mObject_Handle;
00214   if ( s ) // have an old handle?
00215     s->AddStrongRef(ev->AsMdbEnv());
00216   else // need new handle?
00217   {
00218     s = orkinSorting::MakeSorting(ev, this);
00219     mObject_Handle = s;
00220   }
00221   if ( s )
00222     outSorting = s;
00223   return outSorting;
00224 }
00225 
00226 
00227 class morkSortClosure {
00228 public:
00229 
00230   morkEnv*     mSortClosure_Env;
00231   morkSorting* mSortClosure_Sorting;
00232   
00233 public:
00234   morkSortClosure(morkEnv* ev, morkSorting* ioSorting);
00235 };
00236 
00237 morkSortClosure::morkSortClosure(morkEnv* ev, morkSorting* ioSorting)
00238   : mSortClosure_Env(ev), mSortClosure_Sorting(ioSorting)
00239 {
00240 }
00241 
00242 static mdb_order morkRow_Order(const morkRow* inA, const morkRow* inB, 
00243   morkSortClosure* ioClosure)
00244 {
00245   return 0;  
00246 }
00247 
00248 void morkSorting::sort_rows(morkEnv* ev)
00249 {
00250   morkTable* table = mSorting_Table;
00251   if ( table )
00252   {
00253     morkArray* tra = &table->mTable_RowArray;
00254     mork_count count = mSorting_RowArray.mArray_Fill;
00255     if ( this->is_seed_stale() || count != tra->mArray_Fill )
00256       count = this->copy_table_row_array(ev);
00257     
00258     if ( ev->Good() )
00259     {
00260       void** slots = mSorting_RowArray.mArray_Slots;
00261       morkSortClosure closure(ev, this);
00262       
00263       morkQuickSort((mork_u1*) slots, count, sizeof(morkRow*), 
00264         (mdbAny_Order) morkRow_Order, &closure);
00265     }
00266   }
00267   else
00268     this->NilTableError(ev);
00269 }
00270 
00271 mork_count morkSorting::copy_table_row_array(morkEnv* ev)
00272 {
00273   morkArray* tra = &mSorting_Table->mTable_RowArray;
00274   mork_bool bigEnough = mSorting_RowArray.mArray_Size > tra->mArray_Fill;
00275   if ( !bigEnough )
00276     bigEnough = mSorting_RowArray.Grow(ev, tra->mArray_Fill);
00277     
00278   if ( ev->Good() && bigEnough )
00279   {
00280     mSorting_RowArray.mArray_Fill = tra->mArray_Fill;
00281     morkRow** src = (morkRow**) tra->mArray_Slots;
00282     morkRow** dst = (morkRow**) mSorting_RowArray.mArray_Slots;
00283     morkRow** end = dst + tra->mArray_Fill;
00284     
00285     while ( dst < end )
00286       *dst++ = *src++;
00287 
00288     this->sync_with_table_seed();
00289   }
00290     
00291   return mSorting_RowArray.mArray_Fill;
00292 }
00293 
00294 mork_pos
00295 morkSorting::ArrayHasOid(morkEnv* ev, const mdbOid* inOid)
00296 {
00297   MORK_USED_1(ev); 
00298   mork_count count = mSorting_RowArray.mArray_Fill;
00299   mork_pos pos = -1;
00300   while ( ++pos < (mork_pos)count )
00301   {
00302     morkRow* row = (morkRow*) mSorting_RowArray.At(pos);
00303     MORK_ASSERT(row);
00304     if ( row && row->EqualOid(inOid) )
00305     {
00306       return pos;
00307     }
00308   }
00309   return -1;
00310 }
00311 
00312 mork_bool
00313 morkSorting::AddRow(morkEnv* ev, morkRow* ioRow)
00314 {
00315   MORK_USED_1(ioRow);
00316   return ev->Good();
00317 }
00318 
00319 mork_bool
00320 morkSorting::CutRow(morkEnv* ev, morkRow* ioRow)
00321 {
00322   MORK_USED_1(ioRow);
00323   return ev->Good();
00324 }
00325 
00326 
00327 mork_bool
00328 morkSorting::CutAllRows(morkEnv* ev)
00329 {
00330   return ev->Good();
00331 }
00332 
00333 morkSortingRowCursor*
00334 morkSorting::NewSortingRowCursor(morkEnv* ev, mork_pos inRowPos)
00335 {
00336   morkSortingRowCursor* outCursor = 0;
00337   if ( ev->Good() )
00338   {
00339 //    nsIMdbHeap* heap = mSorting_Table->mTable_Store->mPort_Heap;
00340 //    morkSortingRowCursor* cursor = 0;
00341       
00342     // $$$$$
00343     // morkSortingRowCursor* cursor = new(*heap, ev)
00344     //  morkSortingRowCursor(ev, morkUsage::kHeap, heap, this, inRowPos);
00345     // if ( cursor )
00346     // {
00347     //   if ( ev->Good() )
00348     //     outCursor = cursor;
00349     //   else
00350     //     cursor->CutStrongRef(ev);
00351     // }
00352   }
00353   return outCursor;
00354 }
00355 
00356 
00357 //3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
00358 
00359 
00360 morkSortingMap::~morkSortingMap()
00361 {
00362 }
00363 
00364 morkSortingMap::morkSortingMap(morkEnv* ev, const morkUsage& inUsage,
00365   nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap)
00366   : morkNodeMap(ev, inUsage, ioHeap, ioSlotHeap)
00367 {
00368   if ( ev->Good() )
00369     mNode_Derived = morkDerived_kSortingMap;
00370 }
00371 
00372 
00373 //3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789