MFEM v2.0
|
00001 // Copyright (c) 2010, Lawrence Livermore National Security, LLC. Produced at 00002 // the Lawrence Livermore National Laboratory. LLNL-CODE-443211. All Rights 00003 // reserved. See file COPYRIGHT for details. 00004 // 00005 // This file is part of the MFEM library. For more information and source code 00006 // availability see http://mfem.googlecode.com. 00007 // 00008 // MFEM is free software; you can redistribute it and/or modify it under the 00009 // terms of the GNU Lesser General Public License (as published by the Free 00010 // Software Foundation) version 2.1 dated February 1999. 00011 00012 #ifndef MFEM_MEM_ALLOC 00013 #define MFEM_MEM_ALLOC 00014 00015 00016 template <class Elem, int Num> 00017 class StackPart 00018 { 00019 public: 00020 StackPart<Elem, Num> *Prev; 00021 Elem Elements[Num]; 00022 }; 00023 00024 template <class Elem, int Num> 00025 class Stack 00026 { 00027 private: 00028 StackPart <Elem, Num> *TopPart, *TopFreePart; 00029 int UsedInTop, SSize; 00030 public: 00031 Stack() { TopPart = TopFreePart = NULL; UsedInTop = Num; SSize = 0; }; 00032 int Size() { return SSize; }; 00033 void Push (Elem E); 00034 Elem Pop(); 00035 void Clear(); 00036 ~Stack() { Clear(); }; 00037 }; 00038 00039 template <class Elem, int Num> 00040 void Stack <Elem, Num>::Push (Elem E) 00041 { 00042 StackPart <Elem, Num> *aux; 00043 if (UsedInTop == Num) 00044 { 00045 if (TopFreePart == NULL) 00046 aux = new StackPart <Elem, Num>; 00047 else 00048 TopFreePart = (aux = TopFreePart)->Prev; 00049 aux->Prev = TopPart; 00050 TopPart = aux; 00051 UsedInTop = 0; 00052 } 00053 TopPart->Elements[UsedInTop++] = E; 00054 SSize++; 00055 } 00056 00057 template <class Elem, int Num> 00058 Elem Stack <Elem, Num>::Pop() 00059 { 00060 StackPart <Elem, Num> *aux; 00061 if (UsedInTop == 0) 00062 { 00063 TopPart = (aux = TopPart)->Prev; 00064 aux->Prev = TopFreePart; 00065 TopFreePart = aux; 00066 UsedInTop = Num; 00067 } 00068 SSize--; 00069 return TopPart->Elements[--UsedInTop]; 00070 } 00071 00072 template <class Elem, int Num> 00073 void Stack <Elem, Num>::Clear() 00074 { 00075 StackPart <Elem, Num> *aux; 00076 while (TopPart != NULL) 00077 { 00078 TopPart = (aux = TopPart)->Prev; 00079 delete aux; 00080 } 00081 while (TopFreePart != NULL) 00082 { 00083 TopFreePart = (aux = TopFreePart)->Prev; 00084 delete aux; 00085 } 00086 UsedInTop = Num; 00087 SSize = 0; 00088 } 00089 00090 00091 template <class Elem, int Num> 00092 class MemAllocNode 00093 { 00094 public: 00095 MemAllocNode <Elem, Num> *Prev; 00096 Elem Elements[Num]; 00097 }; 00098 00099 template <class Elem, int Num> 00100 class MemAlloc 00101 { 00102 private: 00103 MemAllocNode <Elem, Num> *Last; 00104 int AllocatedInLast; 00105 Stack <Elem *, Num> UsedMem; 00106 public: 00107 MemAlloc() { Last = NULL; AllocatedInLast = Num; }; 00108 Elem *Alloc(); 00109 void Free (Elem *); 00110 void Clear(); 00111 ~MemAlloc() { Clear(); }; 00112 }; 00113 00114 template <class Elem, int Num> 00115 Elem *MemAlloc <Elem, Num>::Alloc() 00116 { 00117 MemAllocNode <Elem, Num> *aux; 00118 if (UsedMem.Size() > 0) 00119 return UsedMem.Pop(); 00120 if (AllocatedInLast == Num) 00121 { 00122 aux = Last; 00123 Last = new MemAllocNode <Elem, Num>; 00124 Last->Prev = aux; 00125 AllocatedInLast = 0; 00126 } 00127 return &(Last->Elements[AllocatedInLast++]); 00128 } 00129 00130 template <class Elem, int Num> 00131 void MemAlloc <Elem, Num>::Free (Elem *E) 00132 { 00133 UsedMem.Push (E); 00134 } 00135 00136 template <class Elem, int Num> 00137 void MemAlloc <Elem, Num>::Clear() 00138 { 00139 MemAllocNode <Elem, Num> *aux; 00140 while (Last != NULL) 00141 { 00142 aux = Last->Prev; 00143 delete Last; 00144 Last = aux; 00145 } 00146 AllocatedInLast = Num; 00147 UsedMem.Clear(); 00148 } 00149 00150 00151 #endif