/Users/deen/code/yugabyte-db/src/yb/yql/pggate/pg_memctx.h
Line | Count | Source |
1 | | //-------------------------------------------------------------------------------------------------- |
2 | | // Copyright (c) YugaByte, Inc. |
3 | | // |
4 | | // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
5 | | // in compliance with the License. You may obtain a copy of the License at |
6 | | // |
7 | | // http://www.apache.org/licenses/LICENSE-2.0 |
8 | | // |
9 | | // Unless required by applicable law or agreed to in writing, software distributed under the License |
10 | | // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express |
11 | | // or implied. See the License for the specific language governing permissions and limitations |
12 | | // under the License. |
13 | | //-------------------------------------------------------------------------------------------------- |
14 | | |
15 | | #ifndef YB_YQL_PGGATE_PG_MEMCTX_H_ |
16 | | #define YB_YQL_PGGATE_PG_MEMCTX_H_ |
17 | | |
18 | | #include <vector> |
19 | | #include <unordered_map> |
20 | | |
21 | | #include <boost/intrusive/list.hpp> |
22 | | |
23 | | #include "yb/yql/pggate/pg_gate_fwd.h" |
24 | | |
25 | | #include "yb/util/status_fwd.h" |
26 | | |
27 | | namespace yb { |
28 | | namespace pggate { |
29 | | |
30 | | // This is the YB counterpart of Postgres's MemoryContext. |
31 | | // YugaByte memory context hold one reference count to PgGate objects such as PgGate::PgStatement. |
32 | | // When Postgres process complete execution, it would release the reference count by destroying |
33 | | // the YugaByte memory context. |
34 | | // |
35 | | // - Each YB Memctx will be associated with a Postgres MemoryContext. |
36 | | // - YB Memctx will be initialized to NULL and later created on its first use. |
37 | | // - When Postgres MemoryContext is destroyed, YB Memctx will be destroyed. |
38 | | // - When Postgres MemoryContext allocates YugaByte object, that YB object will belong to the |
39 | | // associated YB Memctx. The object is automatically destroyed when YB Memctx is destroyed. |
40 | | class PgMemctx { |
41 | | public: |
42 | | typedef std::shared_ptr<PgMemctx> SharedPtr; |
43 | | |
44 | | class Registrable : public boost::intrusive::list_base_hook<> { |
45 | | public: |
46 | 9.26M | virtual ~Registrable() = default; |
47 | | private: |
48 | | PgMemctx* memctx_ = nullptr; |
49 | | friend class PgMemctx; |
50 | | }; |
51 | | |
52 | | // Constructor and destructor. |
53 | | PgMemctx(); |
54 | | virtual ~PgMemctx(); |
55 | | |
56 | | // API: Create(), Destroy(), and Reset() |
57 | | // - Because Postgres process own YugaByte memory context, only Postgres processes should call |
58 | | // these functions to manage YugaByte memory context. |
59 | | // - When Postgres process (a C Program) is exiting, it assumes that all associated memories |
60 | | // are destroyed and will not call Destroy() to free YugaByte memory context. As a result, |
61 | | // PgGate must release the remain YugaByte memory contexts itself. Create(), Destroy(), and |
62 | | // Reset() API uses a global variable for that purpose. When Postgres processes exit, the |
63 | | // global destructor will free all YugaByte memory contexts. |
64 | | |
65 | | // Create yugabyte memory context that will be owned by Postgres process. |
66 | | static PgMemctx *Create(); |
67 | | |
68 | | // Destroy yugabyte memory context that is owned by Postgres process. |
69 | | static CHECKED_STATUS Destroy(PgMemctx *handle); |
70 | | |
71 | | // Clear the content of yugabyte memory context that is owned by Postgres process. |
72 | | // Postgres has Reset() option where it clears the allocated memory for the current context but |
73 | | // keeps all the allocated memory for the child contexts. |
74 | | static CHECKED_STATUS Reset(PgMemctx *handle); |
75 | | |
76 | | void Register(Registrable *obj); |
77 | | static void Destroy(Registrable *obj); |
78 | | |
79 | | // Cache the table descriptor in the memory context to be destroyed later on. |
80 | | void Cache(size_t hash_id, const PgTableDescPtr &table_desc); |
81 | | |
82 | | // Read the table descriptor from cache. |
83 | | void GetCache(size_t hash_id, PgTableDesc **handle); |
84 | | |
85 | | private: |
86 | | // NOTE: |
87 | | // - In Postgres, the objects in the outer context can references to the objects of the nested |
88 | | // context but not vice versa, so it is safe to clear objects of outer context. |
89 | | // - In YugaByte, the above abstraction must be followed, but I am not yet sure that we did. |
90 | | // For now we destroy the yugabyte objects in the current context also as we should. However, |
91 | | // if the objects in nested context might still have referenced to the objects of the outer |
92 | | // memctx, we can delay the PgStatement objects' destruction. |
93 | | void Clear(); |
94 | | |
95 | | // All talbe descriptors that are allocated with this memory context. |
96 | | std::unordered_map<size_t, PgTableDescPtr> tabledesc_map_; |
97 | | |
98 | | boost::intrusive::list<Registrable> registered_objects_; |
99 | | |
100 | | DISALLOW_COPY_AND_ASSIGN(PgMemctx); |
101 | | }; |
102 | | |
103 | | void ClearGlobalPgMemctxMap(); |
104 | | |
105 | | } // namespace pggate |
106 | | } // namespace yb |
107 | | |
108 | | #endif // YB_YQL_PGGATE_PG_MEMCTX_H_ |