File indexing completed on 2026-09-16 09:18:01
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #ifndef NCollection_UBTreeFiller_HeaderFile
0017 #define NCollection_UBTreeFiller_HeaderFile
0018
0019 #include <NCollection_UBTree.hxx>
0020 #include <NCollection_DynamicArray.hxx>
0021
0022 #include <random>
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033 template <class TheObjType, class TheBndType>
0034 class NCollection_UBTreeFiller
0035 {
0036 public:
0037
0038
0039
0040 struct ObjBnd
0041 {
0042 TheObjType myObj;
0043 TheBndType myBnd;
0044
0045 ObjBnd(const TheObjType& theObj, const TheBndType& theBnd)
0046 : myObj(theObj),
0047 myBnd(theBnd)
0048 {
0049 }
0050
0051 ObjBnd()
0052 : myObj(TheObjType()),
0053 myBnd(TheBndType())
0054 {
0055 }
0056 };
0057
0058
0059 typedef NCollection_UBTree<TheObjType, TheBndType> UBTree;
0060 typedef typename UBTree::TreeNode UBTreeNode;
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076 NCollection_UBTreeFiller (UBTree& theTree,
0077 const occ::handle<NCollection_BaseAllocator>& theAlloc=nullptr,
0078 const bool isFullRandom = true)
0079 : myTree(theTree), mySeqPtr(256, theAlloc),
0080 myRandGen (5489u ),
0081 myIsFullRandom (isFullRandom)
0082 {
0083 }
0084
0085
0086 void Add(const TheObjType& theObj, const TheBndType& theBnd)
0087 {
0088 mySeqPtr.Append(ObjBnd(theObj, theBnd));
0089 }
0090
0091
0092
0093
0094
0095
0096
0097
0098 int Fill();
0099
0100
0101
0102
0103
0104 void Reset() { mySeqPtr.Clear(); }
0105
0106
0107
0108
0109
0110
0111
0112 int CheckTree(Standard_OStream& theStream);
0113
0114
0115
0116
0117
0118 ~NCollection_UBTreeFiller()
0119 {
0120 if (mySeqPtr.Length() > 0)
0121 #ifdef OCCT_DEBUG_UBTREE
0122 std::cout << "~NCollection_UBTreeFiller: " << Fill() << " objects added to the tree"
0123 << std::endl;
0124 #else
0125 Fill();
0126 #endif
0127 }
0128
0129 private:
0130
0131 NCollection_UBTreeFiller& operator=(const NCollection_UBTreeFiller&) = delete;
0132
0133 static double checkNode(const UBTreeNode& theNode, const int theLength, int& theNumber);
0134
0135 private:
0136
0137
0138 UBTree& myTree;
0139 NCollection_DynamicArray<ObjBnd> mySeqPtr;
0140 std::mt19937 myRandGen;
0141 bool myIsFullRandom;
0142 };
0143
0144
0145
0146 template <class TheObjType, class TheBndType>
0147 int NCollection_UBTreeFiller<TheObjType, TheBndType>::Fill()
0148 {
0149 int i, nbAdd = mySeqPtr.Length();
0150
0151 if (myIsFullRandom)
0152 {
0153 for (i = nbAdd; i > 0; i--)
0154 {
0155 const int ind = static_cast<int>(static_cast<unsigned int>(myRandGen()) % i);
0156 const ObjBnd& aObjBnd = mySeqPtr(ind);
0157 myTree.Add(aObjBnd.myObj, aObjBnd.myBnd);
0158 mySeqPtr(ind) = mySeqPtr(i - 1);
0159 }
0160 }
0161 else
0162 {
0163 for (i = nbAdd; i > 0; i--)
0164 {
0165 const int ind = i - static_cast<int>(static_cast<unsigned int>(myRandGen()) % i) - 1;
0166 const ObjBnd& aObjBnd = mySeqPtr(ind);
0167 myTree.Add(aObjBnd.myObj, aObjBnd.myBnd);
0168 mySeqPtr(ind) = mySeqPtr(i - 1);
0169 }
0170 }
0171 mySeqPtr.Clear();
0172 return nbAdd;
0173 }
0174
0175
0176
0177 template <class TheObjType, class TheBndType>
0178 int NCollection_UBTreeFiller<TheObjType, TheBndType>::CheckTree(Standard_OStream& theStream)
0179 {
0180 int aNumber(0);
0181 const double aLen = checkNode(myTree.Root(), 0, aNumber);
0182 const double num = (double)aNumber;
0183 const double aLen1 = sqrt(aLen / num);
0184 const double aLen0 = log(num) / log(2.);
0185 char buf[128];
0186 Sprintf(buf, "Checking UBTree:%8d leaves, balance =%7.2f", aNumber, aLen1 / aLen0);
0187 theStream << buf << std::endl;
0188 return aNumber;
0189 }
0190
0191
0192
0193 template <class TheObjType, class TheBndType>
0194 double NCollection_UBTreeFiller<TheObjType, TheBndType>::checkNode(
0195 const typename NCollection_UBTree<TheObjType, TheBndType>::TreeNode& theNode,
0196 const int theLength,
0197 int& theNumber)
0198 {
0199 double aLength;
0200 if (!theNode.IsLeaf())
0201 aLength = (checkNode(theNode.Child(0), theLength + 1, theNumber)
0202 + checkNode(theNode.Child(1), theLength + 1, theNumber));
0203 else
0204 {
0205 theNumber++;
0206 aLength = theLength * theLength;
0207 }
0208 return aLength;
0209 }
0210
0211 #endif