1 ///////////////////////////////////////////////////////////////////////////////
2 // BSD 3-Clause License
3 //
4 // Copyright (c) 2019, Nefelus Inc
5 // All rights reserved.
6 //
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions are met:
9 //
10 // * Redistributions of source code must retain the above copyright notice, this
11 //   list of conditions and the following disclaimer.
12 //
13 // * Redistributions in binary form must reproduce the above copyright notice,
14 //   this list of conditions and the following disclaimer in the documentation
15 //   and/or other materials provided with the distribution.
16 //
17 // * Neither the name of the copyright holder nor the names of its
18 //   contributors may be used to endorse or promote products derived from
19 //   this software without specific prior written permission.
20 //
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 // POSSIBILITY OF SUCH DAMAGE.
32 
33 #pragma once
34 
35 ///
36 /// This file contains the core objects that everything is
37 /// built from.
38 ///
39 /// The core objects are:
40 ///
41 ///  dbId - included
42 ///  dbObjectTable
43 ///  dbObjectPage
44 ///  dbTablePage
45 ///
46 
47 #include "dbAttrTable.h"
48 #include "dbId.h"
49 #include "dbObject.h"
50 #include "odb.h"
51 namespace utl {
52 class Logger;
53 }
54 namespace odb {
55 
56 class _dbDatabase;
57 class _dbProperty;
58 class dbObjectTable;
59 
60 #define DB_ALLOC_BIT 0x80000000
61 #define DB_OFFSET_MASK (~DB_ALLOC_BIT)
62 
63 typedef dbObjectTable* (dbObject::*GetObjTbl_t)(dbObjectType);
64 
65 ///////////////////////////////////////////////////////////////
66 /// _dbObject definition
67 ///////////////////////////////////////////////////////////////
68 class _dbObject : public dbObject
69 {
70  private:
71   uint _oid;
72 
73  public:
74   _dbDatabase* getDatabase() const;
75   dbObjectTable* getTable() const;
76   dbObjectPage* getObjectPage() const;
77   dbObject* getOwner() const;
78   dbObjectType getType() const;
79   uint getOID() const;
80   utl::Logger* getLogger() const;
81 
82   template <class T>
83   friend class dbTable;
84   template <class T>
85   friend class dbArrayTable;
86 };
87 
88 ///////////////////////////////////////////////////////////////
89 /// dbObjectTable definition
90 ///////////////////////////////////////////////////////////////
91 class dbObjectTable
92 {
93  public:
94   // NON-PERSISTANT DATA
95   _dbDatabase* _db;
96   dbObject* _owner;
97   dbObjectType _type;
98   uint _obj_size;
99   dbObjectTable* (dbObject::*_getObjectTable)(dbObjectType type);
100 
101   // PERSISTANT DATA
102   dbAttrTable<dbId<_dbProperty>> _prop_list;
103 
~dbObjectTable()104   virtual ~dbObjectTable(){};
105   dbObjectTable();
106   dbObjectTable(_dbDatabase* db,
107                 dbObject* owner,
108                 dbObjectTable* (dbObject::*m)(dbObjectType),
109                 dbObjectType type,
110                 uint size);
111 
getPropList(uint oid)112   dbId<_dbProperty> getPropList(uint oid) { return _prop_list.getAttr(oid); }
113 
setPropList(uint oid,dbId<_dbProperty> propList)114   void setPropList(uint oid, dbId<_dbProperty> propList)
115   {
116     _prop_list.setAttr(oid, propList);
117   }
118 
119   virtual dbObject* getObject(uint id, ...) = 0;
120 
getObjectTable(dbObjectType type)121   dbObjectTable* getObjectTable(dbObjectType type)
122   {
123     return (_owner->*_getObjectTable)(type);
124   }
125 };
126 
127 ///////////////////////////////////////////////////////////////
128 /// _dbFreeObject definition - free-list object
129 ///////////////////////////////////////////////////////////////
130 
131 class _dbFreeObject : public _dbObject
132 {
133  public:
134   uint _next;
135   uint _prev;
136 };
137 
138 ///////////////////////////////////////////////////////////////
139 /// dbObjectPage definition
140 ///////////////////////////////////////////////////////////////
141 class dbObjectPage
142 {
143  public:
144   // NON-PERSISTANT DATA
145   dbObjectTable* _table;
146   uint _page_addr;
147   uint _alloccnt;
148 
valid_page()149   bool valid_page() const { return _alloccnt != 0; }
150 };
151 
152 ///////////////////////////////////////////////////////////////
153 /// dbObjectTable implementation
154 ///////////////////////////////////////////////////////////////
dbObjectTable()155 inline dbObjectTable::dbObjectTable()
156 {
157   _db = NULL;
158   _owner = NULL;
159 }
160 
dbObjectTable(_dbDatabase * db,dbObject * owner,dbObjectTable * (dbObject::* m)(dbObjectType),dbObjectType type,uint size)161 inline dbObjectTable::dbObjectTable(_dbDatabase* db,
162                                     dbObject* owner,
163                                     dbObjectTable* (dbObject::*m)(dbObjectType),
164                                     dbObjectType type,
165                                     uint size)
166 {
167   _db = db;
168   _owner = owner;
169   _getObjectTable = m;
170   _type = type;
171 
172   // Objects must be greater than 16-bytes
173   assert(size >= sizeof(_dbFreeObject));
174   _obj_size = size;
175 }
176 
177 ///////////////////////////////////////////////////////////////
178 /// _dbObject inlines
179 ///////////////////////////////////////////////////////////////
180 
getImpl()181 inline _dbObject* dbObject::getImpl()
182 {
183   return (_dbObject*) this;
184 }
185 
getImpl()186 inline const _dbObject* dbObject::getImpl() const
187 {
188   return (_dbObject*) this;
189 }
190 
getOID()191 inline uint _dbObject::getOID() const
192 {
193   uint offset = (_oid & DB_OFFSET_MASK);
194   char* base = (char*) this - offset;
195   dbObjectPage* page = (dbObjectPage*) (base - sizeof(dbObjectPage));
196   return page->_page_addr | offset / page->_table->_obj_size;
197 }
198 
getTable()199 inline dbObjectTable* _dbObject::getTable() const
200 {
201   uint offset = (_oid & DB_OFFSET_MASK);
202   char* base = (char*) this - offset;
203   dbObjectPage* page = (dbObjectPage*) (base - sizeof(dbObjectPage));
204   return page->_table;
205 }
206 
getDatabase()207 inline _dbDatabase* _dbObject::getDatabase() const
208 {
209   uint offset = (_oid & DB_OFFSET_MASK);
210   char* base = (char*) this - offset;
211   dbObjectPage* page = (dbObjectPage*) (base - sizeof(dbObjectPage));
212   return page->_table->_db;
213 }
214 
getOwner()215 inline dbObject* _dbObject::getOwner() const
216 {
217   uint offset = (_oid & DB_OFFSET_MASK);
218   char* base = (char*) this - offset;
219   dbObjectPage* page = (dbObjectPage*) (base - sizeof(dbObjectPage));
220   return page->_table->_owner;
221 }
222 
getType()223 inline dbObjectType _dbObject::getType() const
224 {
225   uint offset = (_oid & DB_OFFSET_MASK);
226   char* base = (char*) this - offset;
227   dbObjectPage* page = (dbObjectPage*) (base - sizeof(dbObjectPage));
228   return page->_table->_type;
229 }
230 
getObjectPage()231 inline dbObjectPage* _dbObject::getObjectPage() const
232 {
233   uint offset = (_oid & DB_OFFSET_MASK);
234   char* base = (char*) this - offset;
235   dbObjectPage* page = (dbObjectPage*) (base - sizeof(dbObjectPage));
236   return page;
237 }
238 
239 }  // namespace odb
240