Line data Source code
1 : // Copyright (c) 2019 Made to Order Software Corp. All Rights Reserved
2 : //
3 : // https://snapwebsites.org/project/snapdatabase
4 : // contact@m2osw.com
5 : //
6 : // This program is free software; you can redistribute it and/or modify
7 : // it under the terms of the GNU General Public License as published by
8 : // the Free Software Foundation; either version 2 of the License, or
9 : // (at your option) any later version.
10 : //
11 : // This program is distributed in the hope that it will be useful,
12 : // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : // GNU General Public License for more details.
15 : //
16 : // You should have received a copy of the GNU General Public License along
17 : // with this program; if not, write to the Free Software Foundation, Inc.,
18 : // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 :
20 :
21 : /** \file
22 : * \brief Database file implementation.
23 : *
24 : * Each table uses one or more files. Each file is handled by a dbfile
25 : * object and a corresponding set of blocks.
26 : */
27 :
28 : // self
29 : //
30 : #include "snapdatabase/block/block_top_index.h"
31 :
32 : #include "snapdatabase/block/block_header.h"
33 :
34 :
35 : // last include
36 : //
37 : #include <snapdev/poison.h>
38 :
39 :
40 :
41 : namespace snapdatabase
42 : {
43 :
44 :
45 : // We don't want to do that because each key would have a size which means
46 : // we'd waste a lot of space
47 : //
48 : //struct_description_t g_index_description[] =
49 : //{
50 : // define_description(
51 : // FieldName("pointer")
52 : // , FieldType(struct_type_t::STRUCT_TYPE_REFERENCE)
53 : // ),
54 : // define_description(
55 : // FieldName("key")
56 : // , FieldType(struct_type_t::STRUCT_TYPE_BUFFER32)
57 : // ),
58 : //};
59 :
60 :
61 :
62 : namespace
63 : {
64 :
65 :
66 :
67 : // 'TIDX' -- top index
68 : constexpr struct_description_t g_description[] =
69 : {
70 : define_description(
71 : FieldName("header")
72 : , FieldType(struct_type_t::STRUCT_TYPE_STRUCTURE)
73 : , FieldSubDescription(detail::g_block_header)
74 : ),
75 : define_description(
76 : FieldName("count")
77 : , FieldType(struct_type_t::STRUCT_TYPE_UINT32)
78 : ),
79 : define_description(
80 : FieldName("size")
81 : , FieldType(struct_type_t::STRUCT_TYPE_UINT32)
82 : ),
83 : //define_description(
84 : // FieldName("indexes")
85 : // , FieldType(struct_type_t::STRUCT_TYPE_ARRAY32)
86 : // , FieldDescription(g_index_description)
87 : //),
88 : end_descriptions()
89 : };
90 :
91 :
92 : constexpr descriptions_by_version_t const g_descriptions_by_version[] =
93 : {
94 : define_description_by_version(
95 : DescriptionVersion(0, 1),
96 : DescriptionDescription(g_description)
97 : ),
98 : end_descriptions_by_version()
99 : };
100 :
101 :
102 :
103 : }
104 : // no name namespace
105 :
106 :
107 :
108 :
109 0 : block_top_index::block_top_index(dbfile::pointer_t f, reference_t offset)
110 0 : : block(g_descriptions_by_version, f, offset)
111 : {
112 0 : }
113 :
114 :
115 0 : uint32_t block_top_index::get_count() const
116 : {
117 0 : return static_cast<uint32_t>(f_structure->get_uinteger("count"));
118 : }
119 :
120 :
121 0 : void block_top_index::set_count(uint32_t id)
122 : {
123 0 : f_structure->set_uinteger("count", id);
124 0 : }
125 :
126 :
127 0 : uint32_t block_top_index::get_size() const
128 : {
129 0 : return static_cast<uint32_t>(f_structure->get_uinteger("size"));
130 : }
131 :
132 :
133 0 : void block_top_index::set_size(uint32_t size)
134 : {
135 0 : f_structure->set_uinteger("size", size);
136 0 : }
137 :
138 :
139 0 : reference_t block_top_index::find_index(buffer_t key) const
140 : {
141 : // the start offset is 1 x structure + alignment
142 : //
143 0 : uint32_t offset(f_structure->get_size() + sizeof(reference_t) - 1);
144 0 : offset = offset - offset % sizeof(reference_t);
145 :
146 0 : std::uint8_t const * buffer(data());
147 0 : std::uint32_t const count(get_count());
148 0 : std::uint32_t const size(get_size());
149 0 : int i(0);
150 0 : int j(count);
151 0 : while(i < j)
152 : {
153 0 : int const p((j - i) / 2 + i);
154 0 : uint8_t const * ptr(buffer + p * size);
155 0 : int const r(memcmp(ptr + sizeof(reference_t), key.data(), size));
156 0 : if(r < 0)
157 : {
158 0 : i = p + 1;
159 : }
160 0 : else if(r > 0)
161 : {
162 0 : j = p;
163 : }
164 : else
165 : {
166 0 : return * reinterpret_cast<reference_t const *>(ptr);
167 : }
168 : }
169 :
170 : // TBD: save current position close to point where we can do an insertion
171 :
172 0 : return 0;
173 : }
174 :
175 :
176 :
177 :
178 :
179 :
180 :
181 :
182 :
183 :
184 : } // namespace snapdatabase
185 : // vim: ts=4 sw=4 et
|