source: XIOS/dev/dev_ym/XIOS_COUPLING/extern/remap/src/node.hpp @ 2269

Last change on this file since 2269 was 2269, checked in by ymipsl, 3 years ago
  • Solve memory leak from remapper.
  • shared_ptr add add for manage nodes.

YM

File size: 6.5 KB
Line 
1#ifndef __NODE_H__
2#define __NODE_H__
3
4#include <cassert>
5#include <list>
6#include <vector>
7#include <set>
8#include <map>
9#include <iostream>
10
11#include "triple.hpp"
12#include <memory>
13
14namespace sphereRemap {
15
16struct Circle
17{
18        Coord centre;
19        double radius;
20};
21
22const int MIN_NODE_SZ = 5;
23const int MAX_NODE_SZ = MIN_NODE_SZ*2; /* maximum number of elements per tree-node */
24const int TYPICAL_NODE_SZ = (2*MAX_NODE_SZ + MIN_NODE_SZ)/3;
25const double frac = 0.3;
26
27const int CLOSEST = 1;
28const int FARTHEST = -1;
29
30class CBasicTree;
31struct Node;
32
33
34//#ifdef DEBUG
35//enum alloc_stat { ALLOCATED, DELETED, BORROWED /* mostly means allocated as part of new[] or C++ container */ };
36//struct mem_info { int ref_cnt; enum alloc_stat stat; };
37////extern std::map<void*, struct mem_info> _mem_deb; // reference counter
38//std::map<void*, struct mem_info> _mem_deb; // reference counter
39//
40//// throughout the whole class, ignore NULL pointers
41//class NodePtr
42//{
43//private:
44//      Node* ptr;
45//
46//      void unlink();
47//
48//public:
49//      NodePtr() : ptr(NULL) {}
50//      NodePtr(Node* ptr) : ptr(ptr)
51//      {
52//              if (ptr)
53//              {
54//                      // if ptr does not exist yet just add it, this is not the problem we want so solve here
55//                      // if we do not do this, we run in troubles with pointers on targets allocated as part of array
56//                      // start with 1 since we assume this target is always reachable through the array
57//                      // (we do not want to fix array leaks here)
58//                      if (_mem_deb.count(ptr) == 0)
59//                      {
60//                              _mem_deb[ptr].ref_cnt = 1;
61//                              _mem_deb[ptr].stat = BORROWED;
62//                      }
63////std::cerr << "cnstr ptr " << ptr << " cnt " << _mem_deb[ptr].ref_cnt << std::endl;
64//                      _mem_deb[ptr].ref_cnt += 1;
65//              }
66//      }
67//      NodePtr(const NodePtr& other) : ptr(other.ptr)
68//      {
69////std::cerr << "copy " << ptr << " cnt " << _mem_deb[ptr].ref_cnt << std::endl;
70//              if (ptr) _mem_deb[ptr].ref_cnt += 1;
71//      }
72//      ~NodePtr()
73//      {
74//              if (ptr and _mem_deb.count(ptr)) // if our target has been deleted, that's fine
75//              {
76//                      // Target of ptr is not deleted. We want same behaviour as regular pointer here.
77////std::cerr << "destr ptr " << ptr << " cnt " << _mem_deb[ptr].ref_cnt << std::endl;
78//                      unlink();
79//              }
80//      }
81//      NodePtr& operator=(const NodePtr& other)
82//      {
83//              if (ptr == other.ptr) return *this;
84//              if (ptr and _mem_deb.count(ptr)) // if our target has been deleted, that's fine
85//              {
86////std::cerr << "overr ptr " << ptr << " cnt " << _mem_deb[ptr].ref_cnt << std::endl;
87//                      unlink();
88//              }
89//              ptr = other.ptr;
90//              if (ptr) _mem_deb[ptr].ref_cnt += 1;
91//              return *this;
92//      }
93//      Node& operator*() const
94//      {
95//              assert(ptr);
96//              return *ptr;
97//      }
98//      Node* operator->() const
99//      {
100//              assert(ptr);
101//              return ptr;
102//      }
103//      operator Node*() const
104//      {
105//              return ptr;
106//      }
107//};
108//
109//void memory_report();
110//
111//#else
112//typedef Node* NodePtr;
113//#endif
114
115//typedef Node* NodePtr;
116typedef std::shared_ptr<Node> NodePtr;
117
118struct Node : public std::enable_shared_from_this<Node>
119{
120        int level; /* FIXME leafs are 0 and root is max level? */
121        int leafCount; /* number of leafs that are descendants of this node (the elements in it's cycle) */
122        Coord centre;
123        double radius;
124        std::weak_ptr<Node> parent ;
125        NodePtr ref;
126        std::vector<NodePtr> child;
127        std::list<NodePtr> intersectors;
128        bool reinserted;
129        int updateCount;  // double var;
130        CBasicTree* tree;
131        void *data;
132        int route;
133  bool toDelete ;
134
135        Node() : level(0), leafCount(1), centre(ORIGIN), radius(0), reinserted(false), updateCount(0), toDelete(false) {}
136        Node(const Coord& centre, double radius, void *data)
137                : level(0), leafCount(1), centre(centre), radius(radius), reinserted(false), updateCount(0), data(data), toDelete(false) {}
138
139//#ifdef DEBUG
140////    void *operator new[](size_t size)
141////    {
142////            void *new_array = ::new char[size];
143////std::cerr << "new vector " << new_array << " cnt " << std::endl;
144////            return new_array;
145////    }
146//      void *operator new(size_t size)
147//      {
148//              assert(size == sizeof(Node)); // also sanity? I found this on the internet, better save than sorry
149//              void *new_node = ::new char[size];
150//              assert(_mem_deb.count(new_node) == 0); // sanity that new is returned new pointer (should not happen even if code is broke)
151//              _mem_deb[new_node].ref_cnt = 0;
152//              _mem_deb[new_node].stat = ALLOCATED;
153////std::cerr << "new " << new_node << " cnt " << 0 << std::endl;
154//              return new_node;
155//      }
156//
157////    void operator delete[](void *ptr)
158////    {
159////            if (ptr)
160////            {
161////std::cerr << "delete vector " << ptr << " cnt " << _mem_deb_counter[ptr] << std::endl;
162////                    _mem_deb.erase(ptr);
163////                    ::delete [] ptr;
164////            }
165////    }
166//
167//      void operator delete(void *ptr)
168//      {
169//              if (ptr)
170//              {
171//                      assert(_mem_deb[ptr].ref_cnt); // if this fails it means Matthias is wrong (because he thinks it cannot fail)
172//                      // IF THIS FAILS we handed an invalid pointer to delete (DOUBLE FREE, POINTER ON STL CONTAINER, etc)
173//                      assert(_mem_deb[ptr].stat == ALLOCATED);
174////std::cerr << "delete " << ptr << " cnt " << _mem_deb[ptr].ref_cnt << std::endl;
175//                      // if/since there are still references to this Node, we cannot delete the memory,
176//                      // because otherwise it might get allocate it to a new Node and the reference will point to this node
177//                      // so we mark that delete has been called and free the memory when the last reference disappears
178//                      _mem_deb[ptr].stat = DELETED;
179//              }
180//      }
181//#endif
182
183        void move(const NodePtr node);
184        void remove(const NodePtr node);
185        void inflate(const NodePtr node);
186        void update();
187  void output(std::ostream& flux, int level, int color) ;
188        NodePtr closest(std::vector<NodePtr>& list, int n = CLOSEST);
189        NodePtr farthest(std::vector<NodePtr>& list);
190        void findClosest(int level, NodePtr src, double& minDist, NodePtr &closest);
191
192        void search(NodePtr node);
193        bool centreInside(Node &node);
194        bool intersects(NodePtr node);
195        bool isInside(Node &node);
196        int incluCheck();
197  void checkParent(void) ;
198        void printChildren();
199        void assignRoute(std::vector<int>::iterator& rank, int level);
200        void assignCircleAndPropagateUp(Coord *centres, double *radia, int level);
201        void printLevel(int level);
202        void routeNode(NodePtr node, int level);
203        void routingIntersecting(std::vector<NodePtr>* routingList, NodePtr node);
204        void routeIntersection(std::vector<int>& routes, NodePtr node);
205  void getNodeLevel(int level,std::list<NodePtr>& NodeList) ;
206  bool removeDeletedNodes(int assignLevel) ;
207  void free_descendants();
208};
209
210bool transferNode(NodePtr thIs, NodePtr parent, NodePtr node);
211void findNeighbour(NodePtr thIs, NodePtr node, std::set<NodePtr>& neighbourList);
212NodePtr split(NodePtr);
213NodePtr reinsert(NodePtr);
214NodePtr insert(NodePtr, NodePtr);
215void slim2(NodePtr thIs, int level, int minNodeSize=MIN_NODE_SZ);
216
217}
218#endif
Note: See TracBrowser for help on using the repository browser.