MySQL 8.3.0
Source Code Documentation
lob0impl.h
Go to the documentation of this file.
1/*****************************************************************************
2
3Copyright (c) 2016, 2023, Oracle and/or its affiliates.
4
5This program is free software; you can redistribute it and/or modify it under
6the terms of the GNU General Public License, version 2.0, as published by the
7Free Software Foundation.
8
9This program is also distributed with certain software (including but not
10limited to OpenSSL) that is licensed under separate terms, as designated in a
11particular file or component or in included license documentation. The authors
12of MySQL hereby grant you an additional permission to link the program and
13your derivative works with the separately licensed software that they have
14included with MySQL.
15
16This program is distributed in the hope that it will be useful, but WITHOUT
17ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0,
19for more details.
20
21You should have received a copy of the GNU General Public License along with
22this program; if not, write to the Free Software Foundation, Inc.,
2351 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24
25*****************************************************************************/
26#ifndef lob0impl_h
27#define lob0impl_h
28
29#include "btr0btr.h"
30#include "fut0lst.h"
31#include "lob0first.h"
32#include "lob0lob.h"
33#include "mach0data.h"
34#include "mtr0log.h"
35#include "mtr0mtr.h"
36#include "mtr0types.h"
37
38namespace lob {
39
40struct z_index_entry_t;
41struct z_first_page_t;
42struct z_frag_page_t;
43struct index_entry_t;
44struct first_page_t;
45
46using paddr_t = ulint;
47
48/** The node of page list. The page list is similar to the file list
49(flst_node_t) except that it is completely within one page. */
51 public:
52 /** Offset of the previous node. (2 bytes) */
53 static const uint16_t OFFSET_PREV = 0;
54
55 /** Offset of the next node. (2 bytes) */
56 static const uint16_t OFFSET_NEXT = 2;
57
58 /** The size of a page list node. */
59 static const uint8_t SIZE = 4;
60
61 /** Constructor.
62 @param[in] mtr Mini-transaction context. */
63 explicit plist_node_t(mtr_t *mtr)
64 : m_frame(nullptr), m_node(nullptr), m_mtr(mtr) {}
65
66 /** Default constructor. */
68
69 /** Constructor.
70 @param[in] mtr Mini-transaction context
71 @param[in] frame the page frame of this plist. */
72 plist_node_t(mtr_t *mtr, byte *frame)
73 : m_frame(frame), m_node(nullptr), m_mtr(mtr) {}
74
75 /** Constructor.
76 @param[in] frame the page frame of this plist.
77 @param[in] node the location of plist node. */
78 plist_node_t(byte *frame, byte *node)
79 : m_frame(frame), m_node(node), m_mtr(nullptr) {}
80
81 /** Constructor.
82 @param[in] frame Page frame where the page list node is
83 located.
84 @param[in] node Location of page list node within page
85 frame.
86 @param[in] mtr Mini-transaction context. */
87 plist_node_t(byte *frame, byte *node, mtr_t *mtr)
88 : m_frame(frame), m_node(node), m_mtr(mtr) {}
89
90 /** Copy constructor. */
91 plist_node_t(const plist_node_t &other) = default;
92
93 plist_node_t &operator=(const plist_node_t &) = default;
94
95 /** Check if the current node is before the given node in the
96 page (w.r.t the offset).
97 @param[in] node the other node.
98 @return true if current node is before the given node.
99 @return false if current node is after the given node. */
100 bool is_before(const plist_node_t &node) const {
101 ut_ad(!is_null());
102 ut_ad(!node.is_null());
103 return (addr() < node.addr());
104 }
105
106 /** Initialize the current page list node. The offset of next and
107 previous nodes are set to 0. */
108 void init() {
109 ut_ad(!is_null());
110 ut_ad(m_mtr != nullptr);
111
114 }
115
116 /** Set the offset of the previous node.
117 @param[in] addr the offset of previous node.*/
120 ut_ad(m_mtr != nullptr);
121
123 }
124
125 /** Set the previous page list node.
126 @param[in] prev the previous page list node.*/
127 void set_prev_node(plist_node_t &prev) { set_prev(prev.addr()); }
128
129 /** Set the offset of the next node.
130 @param[in] addr the offset of next node.*/
132 ut_ad(!is_null());
134 ut_ad(m_mtr != nullptr);
135
137 }
138
139 /** Set the next page list node.
140 @param[in] next the next page list node.*/
141 void set_next_node(const plist_node_t &next) { set_next(next.addr()); }
142
143 /** Get the offset of the previous page list node.
144 @return offset of previous node of the page list. */
146
147 /** Get the offset of the next page list node.
148 @return offset of next node of the page list. */
150
151 /** Get the next page list node.
152 @return next node of the page list. */
155 byte *node = nullptr;
156
157 if (addr != 0) {
158 node = m_frame + addr;
160 }
161
162 return (plist_node_t(m_frame, node, m_mtr));
163 }
164
165 /** Get the previous page list node.
166 @return previous node of the page list. */
169 byte *node = nullptr;
170
171 if (addr != 0) {
173 node = m_frame + addr;
174 }
175
176 return (plist_node_t(m_frame, node, m_mtr));
177 }
178
179 /** Obtain the offset of the page list node within the given
180 page frame.
181 @return offset from the beginning of the page. */
182 paddr_t addr() const {
183 return ((m_node == nullptr) ? 0 : (m_node - m_frame));
184 }
185
186 /** Obtain the memory location of the page list node.
187 @return the pointer to the page list node. */
188 byte *ptr() const { return (m_node); }
189
190 /** Check if the given page list node is null.
191 @return true if null, false otherwise. */
192 bool is_null() const { return (m_node == nullptr); }
193
194 /** Print the page list node into the given output stream.
195 @param[in] out the output stream.
196 @return the output stream. */
197 std::ostream &print(std::ostream &out) const {
198 out << "[plist_node_t: next=" << get_next() << ", prev=" << get_prev()
199 << ", this=" << addr() << ", frame=" << (void *)m_frame
200 << ", m_node=" << (void *)m_node << "]";
201 return (out);
202 }
203
204 /** Set the page frame to the given value.
205 @param[in] frame the page frame */
206 void set_frame(byte *frame) { m_frame = frame; }
207
208 /** Set the page list node to the given value.
209 @param[in] node the page list node. */
210 void set_node(byte *node) { m_node = node; }
211
212 /** Set the mini-transaction context to the given value.
213 @param[in] mtr Mini-transaction context. */
214 void set_mtr(mtr_t *mtr) { m_mtr = mtr; }
215
216 /** Get the page frame where this page list exists.
217 @return the page frame. */
218 byte *get_frame() const { return (m_frame); }
219
220 bool is_equal(const plist_node_t &that) const {
221 if (m_node == nullptr || that.m_node == nullptr) {
222 return (false);
223 }
224 return (m_node == that.m_node);
225 }
226
227 private:
228 /** The page frame where this page list exists. */
229 byte *m_frame;
230
231 /** The plist node is located at this address. */
232 byte *m_node;
233
234 /** The mini-transaction context. */
236};
237
238inline std::ostream &operator<<(std::ostream &out, const plist_node_t &obj) {
239 return (obj.print(out));
240}
241
242/** The base node of page list. */
244 /** The offset where the length of the page list is stored.
245 This is 4 bytes long.*/
246 static const ulint OFFSET_LEN = 0;
247
248 /** The offset where the first node is located.
249 This is 2 bytes long. */
250 static const ulint OFFSET_FIRST = 4;
251
252 /** The offset where the last node is located.
253 This is 2 bytes long. */
254 static const ulint OFFSET_LAST = 6;
255
256 /** The total size (in bytes) of a page list base node. */
257 static const ulint SIZE = 8;
258
259 plist_base_node_t(byte *frame, byte *base, mtr_t *mtr)
260 : m_frame(frame), m_base(base), m_mtr(mtr) {}
261
262 void init() {
263 ut_ad(m_mtr != nullptr);
264
268 }
269
270 void remove(plist_node_t &node) {
271 ut_ad(m_mtr != nullptr);
272
273 plist_node_t prev = node.get_prev_node();
274 plist_node_t next = node.get_next_node();
275
276 if (prev.is_null()) {
277 set_first(next.addr());
278 } else {
279 prev.set_next(next.addr());
280 }
281
282 if (next.is_null()) {
283 set_last(prev.addr());
284 } else {
285 next.set_prev(prev.addr());
286 }
287
288 node.set_next(0);
289 node.set_prev(0);
290
291 decr_len();
292 }
293
295 ut_ad(m_mtr != nullptr);
296
297 if (get_len() == 0) {
298 add_to_empty(node);
299 } else {
300 paddr_t cur_addr = node.addr();
301 paddr_t first_addr = get_first();
302 plist_node_t first_node = get_node(first_addr);
303 node.set_next(first_addr);
304 node.set_prev(0);
305 first_node.set_prev(cur_addr);
306 set_first(cur_addr);
307 incr_len();
308 }
309 }
310
311 /** Insert node2 after node1. */
313 ut_ad(m_mtr != nullptr);
314
315 if (node1.is_null()) {
316 push_back(node2);
317 } else {
318 plist_node_t node3 = node1.get_next_node();
319 node1.set_next_node(node2);
320 node2.set_next_node(node3);
321
322 if (node3.is_null()) {
323 set_last(node2.addr());
324 } else {
325 node3.set_prev_node(node2);
326 }
327
328 node2.set_prev_node(node1);
329
330 incr_len();
331 }
332 }
333
334 /** Insert node2 before node3. */
336 ut_ad(m_mtr != nullptr);
337
338 if (node3.is_null()) {
339 push_back(node2);
340 } else {
341 plist_node_t node1 = node3.get_prev_node();
342
343 if (node1.is_null()) {
344 set_first(node2.addr());
345 } else {
346 node1.set_next_node(node2);
347 }
348
349 node2.set_next_node(node3);
350 node3.set_prev_node(node2);
351 node2.set_prev_node(node1);
352
353 incr_len();
354 }
355 }
356
358 ut_ad(m_mtr != nullptr);
359 ut_ad(get_len() == 0);
360
361 set_first(node.addr());
362 set_last(node.addr());
363 incr_len();
364 }
365
367 ut_ad(m_mtr != nullptr);
368
369 if (get_len() == 0) {
370 add_to_empty(node);
371 } else {
372 paddr_t cur_addr = node.addr();
373 paddr_t last_addr = get_last();
374 plist_node_t last_node = get_node(last_addr);
375 node.set_next(0);
376 node.set_prev_node(last_node);
377 last_node.set_next(cur_addr);
378 set_last(cur_addr);
379 incr_len();
380 }
381 }
382
383 bool empty() const { return (get_len() == 0); }
384
386
389 }
390
393
394 if (!empty()) {
395 byte *node = m_frame + get_first();
396 result.set_node(node);
397 }
398 return (result);
399 }
400
402
405
406 if (!empty()) {
407 result.set_node(m_frame + get_last());
408 }
409
410 return (result);
411 }
412
413 void set_len(ulint len) {
414 ut_ad(m_mtr != nullptr);
415
417 }
418
419 void incr_len() {
420 ut_ad(m_mtr != nullptr);
421
424 }
425
426 void decr_len() {
427 ut_ad(m_mtr != nullptr);
428
430
431 ut_ad(len > 0);
432
434 }
435
437 ut_ad(m_mtr != nullptr);
438
440 }
441
443 ut_ad(m_mtr != nullptr);
444
446 }
447
449 byte *node = m_frame + addr;
450 return (plist_node_t(m_frame, node, m_mtr));
451 }
452
453 paddr_t addr() const { return (m_base - m_frame); }
454
455 std::ostream &print(std::ostream &out) const {
456 out << "[plist_base_node_t: len=" << get_len() << ", first=" << get_first()
457 << ", last=" << get_last() << ", this=" << addr() << "]";
458 return (out);
459 }
460
461 std::ostream &print_list(std::ostream &out) const {
462 print(out);
463 out << std::endl;
464
465 for (plist_node_t cur = get_first_node(); !cur.is_null();
466 cur = cur.get_next_node()) {
467 out << cur << std::endl;
468 }
469 return (out);
470 }
471
472#ifdef UNIV_DEBUG
473 /** Validate the page list.
474 @return true if valid, false otherwise. */
475 bool validate() const;
476#endif /* UNIV_DEBUG */
477
478 byte *m_frame;
479 byte *m_base;
481};
482
483inline std::ostream &operator<<(std::ostream &out,
484 const plist_base_node_t &obj) {
485 return (obj.print(out));
486}
487
489const ulint FRAG_ID_NULL = std::numeric_limits<uint16_t>::max();
490const ulint KB16 = 16 * 1024;
491
492/** The node page (also can be called as the index page) contains a list of
493index_entry_t objects. */
494struct node_page_t : public basic_page_t {
495 /** Version information. One byte. */
498
501 }
502
503 /** Default ctor */
504 node_page_t() = default;
505
506 node_page_t(buf_block_t *block, mtr_t *mtr) : basic_page_t(block, mtr) {}
507
509 : basic_page_t(block, mtr, index) {}
510
512 : basic_page_t(nullptr, mtr, index) {}
513
514 /** Constructor
515 @param[in] block the buffer block. */
517
518 /** Import the node page or the index page.
519 @param[in] trx_id transaction identifier. */
520 void import(trx_id_t trx_id);
521
522 buf_block_t *alloc(first_page_t &first_page, bool bulk);
523
525 m_block =
526 buf_page_get(page_id, page_size, RW_X_LATCH, UT_LOCATION_HERE, m_mtr);
527 return (m_block);
528 }
529
530 void dealloc() {
532 m_block = nullptr;
533 }
534
535 static ulint payload() {
537 }
538
539 static ulint max_space_available() { return (payload()); }
540
541 /** Get the number of index entries this page can hold.
542 @return Number of index entries this page can hold. */
543 static ulint node_count();
544
548 }
549
550 byte *nodes_begin() const { return (frame() + LOB_PAGE_DATA); }
551};
552
553/** An entry representing one fragment page. */
555 public:
556 /** Offset within frag entry pointing to prev frag entry. */
557 static const ulint OFFSET_PREV = 0;
558
559 /** Offset within frag entry pointing to next frag entry. */
561
562 /** Offset within frag entry holding the page number of frag page. */
564
565 /** Number of used fragments. */
567
568 /** Used space in bytes. */
570
571 /** Total free space in bytes. */
573
574 /** The biggest free frag space in bytes. */
576
577 /** Total size of one frag entry. */
578 static const ulint SIZE = OFFSET_BIG_FREE_LEN + 2;
579
580 /** Constructor. */
581 z_frag_entry_t(flst_node_t *node, mtr_t *mtr) : m_node(node), m_mtr(mtr) {}
582
583 /** Constructor. */
585
586 /** Constructor. */
588
589 /** Initialize the fragment entry contents. For this to correctly
590 work, the current object must be initialized with proper file list
591 node and the mini-transaction context. */
592 void init() {
593 ut_ad(m_mtr != nullptr);
594 ut_ad(m_node != nullptr);
595
599 set_n_frags(0);
600 set_used_len(0);
603 }
604
605 /** Set the current fragment entry to null. */
606 void set_null() { m_node = nullptr; }
607
608 /** Check if the current fragment entry is null.
609 @return true if the current fragment entry is null, false otherwise. */
610 bool is_null() const { return (m_node == nullptr); }
611
613 page_t *frame = page_align(m_node);
614 page_no_t page_no = mach_read_from_4(frame + FIL_PAGE_OFFSET);
615 uint16_t offset = static_cast<uint16_t>(m_node - frame);
616 ut_ad(offset < UNIV_PAGE_SIZE);
617 return (fil_addr_t(page_no, offset));
618 }
619
620 /** Update the current fragment entry with information about
621 the given fragment page.
622 @param[in] frag_page the fragment page whose information
623 will be stored in current fragment entry. */
624 void update(const z_frag_page_t &frag_page);
625
626 /** Remove this node from the given list.
627 @param[in] bnode the base node of the list from which to remove
628 current node. */
630 ut_ad(m_mtr != nullptr);
631
632 flst_remove(bnode, m_node, m_mtr);
633 }
634
635 /** Add this node as the last node in the given list.
636 @param[in] bnode the base node of the file list. */
638 ut_ad(m_mtr != nullptr);
639
640 flst_add_last(bnode, m_node, m_mtr);
641 }
642
643 /** Add this node as the first node in the given list.
644 @param[in] bnode the base node of the file list. */
646 ut_ad(m_mtr != nullptr);
647
648 flst_add_first(bnode, m_node, m_mtr);
649 }
650
651 /** Point to another frag entry.
652 @param[in] node point to this file list node. */
653 void reset(flst_node_t *node) { m_node = node; }
654
655 /** Set the previous frag entry as null. */
657 ut_ad(m_mtr != nullptr);
658
660 }
661
662 /** Set the previous frag entry as null. */
663 void set_prev(const fil_addr_t &addr) {
664 ut_ad(m_mtr != nullptr);
665
667 }
668
669 /** Get the location of previous frag entry. */
672 }
673
674 /** Set the next frag entry as null. */
676 ut_ad(m_mtr != nullptr);
677
679 }
680
681 /** Set the next frag entry. */
682 void set_next(const fil_addr_t &addr) {
683 ut_ad(m_mtr != nullptr);
684
686 }
687
688 /** Get the location of next frag entry. */
691 }
692
693 /** Get the frag page number. */
696 }
697
698 /** Set the frag page number. */
699 void set_page_no(page_no_t page_no) const {
700 ut_ad(m_mtr != nullptr);
701
703 }
704
705 /** Free the fragment page pointed to by this entry.
706 @param[in] mtr Mini-transaction to be used for this operation.
707 @param[in] index The index to which this LOB belongs. */
708 void free_frag_page(mtr_t *mtr, dict_index_t *index);
709
710 /** Get the frag page number. */
713 }
714
715 /** Set the frag page number. */
716 void set_n_frags(ulint frags) const {
717 ut_ad(m_mtr != nullptr);
718
720 }
721
722 /** Get the used bytes. */
725 }
726
727 /** Set the used bytes. */
728 void set_used_len(ulint used) const {
729 ut_ad(m_mtr != nullptr);
730
732 }
733
734 /** Get the total cumulative free bytes. */
737 }
738
739 /** Get the biggest free frag bytes. */
742 }
743
744 /** Set the total free bytes. */
746 ut_ad(m_mtr != nullptr);
747
749 }
750
751 /** Set the big free frag bytes. */
753 ut_ad(m_mtr != nullptr);
754
756 }
757
758 void purge(flst_base_node_t *used_lst, flst_base_node_t *free_lst);
759
760 std::ostream &print(std::ostream &out) const;
761
762 private:
763 /** The location where the fragment entry node is located. */
765
766 /** The mini-transaction context for operating on this fragment
767 entry. */
769};
770
771inline std::ostream &operator<<(std::ostream &out, const z_frag_entry_t &obj) {
772 return (obj.print(out));
773}
774
775/** An index page containing an array of z_index_entry_t objects. */
777 /** Version information. One byte. */
780
781 /** Constructor.
782 @param[in] mtr mini-transaction context. */
783 explicit z_index_page_t(mtr_t *mtr) : m_block(nullptr), m_mtr(mtr) {}
784
785 /** Constructor.
786 @param[in] block the buffer block.
787 @param[in] mtr mini-transaction context.
788 @param[in] index the index to which the LOB belongs. */
790 : m_block(block), m_mtr(mtr), m_index(index) {}
791
792 /** Constructor.
793 @param[in] mtr mini-transaction context.
794 @param[in] index the index to which the LOB belongs. */
796 : z_index_page_t(nullptr, mtr, index) {}
797
798 /** Constructor
799 @param[in] block the buffer block. */
801 : z_index_page_t(block, nullptr, nullptr) {}
802
803 /** Constructor.
804 @param[in] block the buffer block.
805 @param[in] index the index to which the LOB belongs. */
807 : z_index_page_t(block, nullptr, index) {}
808
809 /** Write the space identifier to the page header, without generating
810 redo log records.
811 @param[in] space_id the space identifier. */
814 nullptr);
815 }
816
817 /** Set the correct page type. */
818 void set_page_type(mtr_t *mtr) {
820 MLOG_2BYTES, mtr);
821 }
822
825 }
826
827 /** Set the next page number. */
829 ut_ad(m_mtr != nullptr);
830
832 }
833
834 /** Get the page number. */
837 }
838
839 /** Get the next page number. */
842 }
843
844 /** Allocate an ZLOB index page.
845 @return the buffer block of the allocated zlob index page. */
846 buf_block_t *alloc(z_first_page_t &first, bool bulk);
847
848 void import(trx_id_t trx_id);
849
850 /** Load the given compressed LOB index page.
851 @param[in] page_no compressed LOB index page number.
852 @return the buffer block of the given page number. */
854 page_id_t page_id(dict_index_get_space(m_index), page_no);
856 m_block =
857 buf_page_get(page_id, page_size, RW_X_LATCH, UT_LOCATION_HERE, m_mtr);
858
860 return (m_block);
861 }
862
863 void dealloc() {
865 m_block = nullptr;
866 }
867
868 void init(flst_base_node_t *free_lst, mtr_t *mtr);
869
870 ulint payload() const {
872
873 return (page_size.physical() - FIL_PAGE_DATA_END - LOB_PAGE_DATA);
874 }
875
877
878 byte *frame() const { return (buf_block_get_frame(m_block)); }
879
880 /** The buffer block of the compressed LOB index page. */
882
883 /** The mini-transaction context. */
885
886 /** The index to which the LOB belongs. */
888};
889
890/** The data page holding the zlob. */
892 /** Version information. One byte. */
894
895 /* The length of compressed data stored in this page. */
897
898 /* The transaction that created this page. */
900
901 /* The data stored in this page begins at this offset. */
903
906 return (page_size.physical() - OFFSET_DATA_BEGIN - FIL_PAGE_DATA_END);
907 }
908
910 : m_block(nullptr), m_mtr(mtr), m_index(index) {}
911
913 : m_block(block), m_mtr(mtr), m_index(index) {}
914
915 /* Constructor.
916 @param[in] block the buffer block. */
918 : m_block(block), m_mtr(nullptr), m_index(nullptr) {}
919
920 /** Write the space identifier to the page header, without generating
921 redo log records.
922 @param[in] space_id the space identifier. */
925 nullptr);
926 }
927
928 /** Allocate one data page.
929 @param[in] hint hint page number for allocation.
930 @param[in] bulk true if bulk operation (OPCODE_INSERT_BULK)
931 false otherwise.
932 @return the allocated buffer block. */
933 buf_block_t *alloc(page_no_t hint, bool bulk);
934
935 /** Free this data page holding the zlob data. */
936 void dealloc() {
938 m_block = nullptr;
939 }
940
941 /** Set the correct page type. */
943 ut_ad(m_mtr != nullptr);
944
947 }
948
950 ut_ad(m_mtr != nullptr);
951
953 }
954
955 /** Set the next page. */
956 void set_next_page(page_no_t page_no) {
957 ut_ad(m_mtr != nullptr);
958
960 }
961
962 void init() {
963 ut_ad(m_mtr != nullptr);
964
968 set_data_len(0);
969 set_trx_id(0);
970 }
971
972 byte *begin_data_ptr() const { return (frame() + OFFSET_DATA_BEGIN); }
973
974 void set_data_len(ulint len) {
975 ut_ad(m_mtr != nullptr);
976
978 }
979
982 }
983
985 ut_ad(m_mtr != nullptr);
986
987 byte *ptr = frame() + OFFSET_TRX_ID;
988 mach_write_to_6(ptr, tid);
989 mlog_log_string(ptr, 6, m_mtr);
990 }
991
992 /** Update the header with given transaction identifier, without
993 writing redo log records.
994 @param[in] tid transaction identifier.*/
996 byte *ptr = frame() + OFFSET_TRX_ID;
997 mach_write_to_6(ptr, tid);
998 }
999
1000 /** Get the page number. */
1003 }
1004
1006 page_no_t page_no = get_page_no();
1007 return (fil_addr_t(page_no, OFFSET_DATA_BEGIN));
1008 }
1009
1010 byte *frame() const { return (buf_block_get_frame(m_block)); }
1011
1015};
1016
1017/** A frag nodes page containing an array of z_frag_entry_t objects. */
1019 /** Version information. One byte. */
1022
1024 : m_block(nullptr), m_mtr(mtr), m_index(index) {}
1025
1026 /** Constructor
1027 @param[in] block the buffer block.*/
1029 : m_block(block), m_mtr(nullptr), m_index(nullptr) {}
1030
1031 /** Write the space identifier to the page header, without generating
1032 redo log records.
1033 @param[in] space_id the space identifier. */
1036 nullptr);
1037 }
1038
1039 /** Set the correct page type. */
1041 ut_ad(m_mtr != nullptr);
1042
1045 }
1046
1047 /** Set the next page number. */
1049 ut_ad(m_mtr != nullptr);
1050
1052 }
1053
1055 ut_ad(m_mtr != nullptr);
1056
1058 }
1059
1060 /** Get the page number. */
1063 }
1064
1065 /** Get the next page number. */
1067 return (mach_read_from_4(frame() + FIL_PAGE_NEXT));
1068 }
1069
1070 /** Allocate a fragment nodes page.
1071 @return buffer block of the allocated fragment nodes page or nullptr. */
1072 buf_block_t *alloc(z_first_page_t &first, bool bulk);
1073
1074 void dealloc() {
1076 m_block = nullptr;
1077 }
1078
1079 /** Load the given compressed LOB fragment page.
1080 @param[in] page_no compressed LOB fragment page number.
1081 @return the buffer block of the given page number. */
1083 page_id_t page_id(dict_index_get_space(m_index), page_no);
1085 m_block =
1086 buf_page_get(page_id, page_size, RW_X_LATCH, UT_LOCATION_HERE, m_mtr);
1087
1089
1090 return (m_block);
1091 }
1092
1093 void init(flst_base_node_t *free_lst) {
1094 ut_ad(m_mtr != nullptr);
1095
1097 for (ulint i = 0; i < n; ++i) {
1098 byte *ptr = frame() + LOB_PAGE_DATA;
1099 ptr += (i * z_frag_entry_t::SIZE);
1101 entry.init();
1102 entry.push_back(free_lst);
1103 }
1104 }
1105
1106 ulint payload() const {
1107 const page_size_t page_size = dict_table_page_size(m_index->table);
1108 return (page_size.physical() - FIL_PAGE_DATA_END - LOB_PAGE_DATA);
1109 }
1110
1112 return (payload() / z_frag_entry_t::SIZE);
1113 }
1114
1115 byte *frame() const { return (buf_block_get_frame(m_block)); }
1116
1117 /** The buffer block of the fragment page. */
1119
1120 /** The mini-transaction context. */
1122
1123 /** The index to which the LOB belongs. */
1125}; // struct z_frag_node_page_t
1126
1127/** Print information about the given compressed lob.
1128@param[in] index the index dictionary object.
1129@param[in] ref the LOB reference
1130@param[out] out the output stream where information is printed.
1131@return DB_SUCCESS on success, or an error code. */
1132dberr_t z_print_info(const dict_index_t *index, const lob::ref_t &ref,
1133 std::ostream &out);
1134
1135/** The fragment node represents one fragment. */
1137 /** The offset where the length of fragment is stored. The length
1138 includes both the payload and the meta data overhead. */
1140
1141 /** The offset where fragment id is stored. */
1142 static const ulint OFFSET_FRAG_ID = OFFSET_LEN + 2;
1143
1144 /** The offset where fragment data is stored. */
1146
1147 /** The size of a page directory entry in a fragment page in bytes.
1148 This must be equal to z_frag_page_t::SIZE_OF_PAGE_DIR_ENTRY*/
1150
1151 /** Constructor.
1152 @param[in] node Page list node.
1153 @param[in] mtr Mini-transaction. */
1154 frag_node_t(const plist_node_t &node, mtr_t *mtr)
1155 : m_node(node), m_mtr(mtr) {}
1156
1158
1159 /** Constructor.
1160 @param[in] frame Page frame where the fragment node is
1161 located.
1162 @param[in] ptr Location of fragment node within page
1163 frame.
1164 @param[in] mtr Mini-transaction context. */
1165 frag_node_t(byte *frame, byte *ptr, mtr_t *mtr)
1166 : m_node(frame, ptr, mtr), m_mtr(mtr) {}
1167
1168 /** Amount of space that will be used up by meta data. When a free
1169 space is taken from the fragment page to be used as a fragment
1170 node, header and footer will be the overhead. Footer is the page dir
1171 entry. The page dir entry may not be contiguous with the fragment.*/
1173
1174 /** Only the header size. Don't include the page dir entry size here.*/
1175 static ulint header_size() { return (OFFSET_DATA); }
1176
1177 /** Constructor.
1178 @param[in] frame Page frame where the fragment node is
1179 located.
1180 @param[in] ptr Location of fragment node within page
1181 frame.
1182 @param[in] len Length of the fragment.
1183 @param[in] mtr Mini-transaction context. */
1184 frag_node_t(byte *frame, byte *ptr, ulint len, mtr_t *mtr)
1185 : m_node(frame, ptr, mtr), m_mtr(mtr) {
1186 ut_ad(mtr != nullptr);
1187
1189 }
1190
1191 byte *frag_begin() const { return (m_node.ptr() + OFFSET_DATA); }
1192
1193 byte *data_begin() const { return (m_node.ptr() + OFFSET_DATA); }
1194
1196 ut_ad(m_mtr != nullptr);
1197
1199 }
1200
1201 /** Increment the total length of this fragment by 2 bytes. */
1203 ut_ad(m_mtr != nullptr);
1204
1208 }
1209
1210 /** Decrement the total length of this fragment by 2 bytes. */
1212 ut_ad(m_mtr != nullptr);
1213
1217 }
1218
1219 bool is_before(const frag_node_t &frag) const {
1220 return (m_node.is_before(frag.m_node));
1221 }
1222
1224 ut_ad(m_mtr != nullptr);
1225
1227 m_mtr);
1228 }
1229
1231 ut_ad(m_mtr != nullptr);
1232
1234 }
1235
1238 }
1239
1240 /** Get the space available in this fragment for storing data. */
1241 ulint payload() const { return (get_total_len() - header_size()); }
1242
1243 /** Get the total length of this fragment, including its metadata. */
1245 return (mach_read_from_2(m_node.ptr() + OFFSET_LEN));
1246 }
1247
1248 /** Get the offset of the current fragment within page.
1249 @return the offset of the current fragment within. */
1250 paddr_t addr() const { return (m_node.addr()); }
1251
1252 /** Gets the pointer to the beginning of the current fragment. Note
1253 that the beginning of the fragment contains meta data.
1254 @return pointer to the beginning of the current fragment. */
1255 byte *ptr() const {
1256 ut_ad(!m_node.is_null());
1257 return (m_node.ptr());
1258 }
1259
1260 /** Gets the pointer just after the current fragment. The pointer
1261 returned does not belong to this fragment. This is used to check
1262 adjacency.
1263 @return pointer to the end of the current fragment. */
1264 byte *end_ptr() const {
1265 ut_ad(!m_node.is_null());
1266 return (ptr() + get_total_len());
1267 }
1268
1269 /** Get the page frame.
1270 @return the page frame. */
1271 byte *frame() const { return (m_node.get_frame()); }
1272
1273 std::ostream &print(std::ostream &out) const {
1274 if (!m_node.is_null()) {
1275 ulint len = get_total_len();
1276 out << "[frag_node_t: " << m_node << ", len=" << len << "/" << payload()
1277 << ", frag_id=" << get_frag_id() << "]";
1278 } else {
1279 out << "[frag_node_t: null, len=0]";
1280 }
1281 return (out);
1282 }
1283
1285 ut_ad(!is_null());
1287 return (frag_node_t(next, m_mtr));
1288 }
1289
1291
1293
1295 ut_ad(!is_null());
1297 return (frag_node_t(prev, m_mtr));
1298 }
1299
1300 /** Merge the current fragment node with the given next fragment node.
1301 This will succeed only if they are adjacent to each other.
1302 Detailed Note: There is a new page type FIL_PAGE_TYPE_ZLOB_FRAG_ENTRY
1303 - and we can call it the fragment pages. Each fragment page contains
1304 one or more fragments. Each fragment is represented by a frag_node_t.
1305 And each fragment can be of different size. Consider a fragment page
1306 containing 4 fragments - f1, f2, f3 and f4. Suppose we free f2 and
1307 f3, then we can merge them into one single bigger fragment which is
1308 free.
1309 @param[in] next the next fragment.
1310 @return true if merge done, false otherwise. */
1311 bool merge(frag_node_t &next) {
1312 ut_ad(m_mtr != nullptr);
1313
1314 byte *p1 = ptr();
1315 ulint len1 = get_total_len();
1316 byte *p2 = next.ptr();
1317 ulint len2 = next.get_total_len();
1318
1319 if (p2 == (p1 + len1)) {
1320 set_total_len(len1 + len2);
1321 return (true);
1322 }
1323
1324 return (false);
1325 }
1326
1327 bool is_null() const { return (m_node.is_null()); }
1328
1329 bool is_equal(const frag_node_t &that) const {
1330 return (m_node.is_equal(that.m_node));
1331 }
1332
1333 bool is_equal(const plist_node_t &node) const {
1334 return (m_node.is_equal(node));
1335 }
1336
1337 /** The page list node. */
1339
1340 private:
1341 /** The mini-transaction context. It is only in-memory. */
1343};
1344
1345inline std::ostream &operator<<(std::ostream &out, const frag_node_t &obj) {
1346 return (obj.print(out));
1347}
1348
1349/** The fragment page. This page will contain fragments from different
1350zlib streams. */
1352 /** Version information. One byte. */
1354
1355 /** The location of z_frag_entry_t for this page. */
1357
1358 /** The offset within page where the free space list begins. */
1360
1361 /** The offset within page where the fragment list begins. */
1364
1365 /** The offset within page where the fragments can occupy . */
1368
1369 /** Offset of number of page directory entries (from end) */
1371
1372 /** Offset of first page directory entry (from end) */
1375
1376 static const ulint SIZE_OF_PAGE_DIR_ENTRY = 2; /* bytes */
1377
1378 /** Constructor.
1379 @param[in] block Buffer block containing the fragment page.
1380 @param[in] mtr Mini-transaction context.
1381 @param[in] index Clustered index to which LOB belongs. */
1383 : m_block(block), m_mtr(mtr), m_index(index) {
1386 }
1387
1388 /** Constructor.
1389 @param[in] mtr Mini-transaction context.
1390 @param[in] index Clustered index to which LOB belongs. */
1392 : z_frag_page_t(nullptr, mtr, index) {}
1393
1394 /** Constructor.
1395 @param[in] block the buffer block containing the fragment page.*/
1397 : m_block(block), m_mtr(nullptr), m_index(nullptr) {
1400 }
1401
1402 /** Write the space identifier to the page header, without generating
1403 redo log records.
1404 @param[in] space_id the space identifier. */
1407 nullptr);
1408 }
1409
1412
1415 entry.update(*this);
1416 }
1417
1420 }
1421
1424 const page_size_t page_size = dict_table_page_size(m_index->table);
1425 return (fut_get_ptr(space, page_size, addr, RW_X_LATCH, m_mtr));
1426 }
1427
1430 const page_size_t page_size = dict_table_page_size(m_index->table);
1431 return (fut_get_ptr(space, page_size, addr, RW_S_LATCH, m_mtr));
1432 }
1433
1434 void set_frag_entry(const fil_addr_t &addr) const {
1435 ut_a(addr.boffset < get_page_size());
1436 return (flst_write_addr(frame() + OFFSET_FRAG_ENTRY, addr, m_mtr));
1437 }
1438
1439 /** Obtain the file address of the fragment entry that denotes the
1440 current fragment page.
1441 @return the file address of the fragment entry. */
1444 }
1445
1446 void set_frag_entry_null() const {
1448 }
1449
1452 return (mach_read_from_2(ptr));
1453 }
1454
1458 }
1459
1460 bool is_border_frag(const frag_node_t &node) const {
1461 return (slots_end_ptr() == node.end_ptr());
1462 }
1463
1464 byte *slots_end_ptr() const {
1466 byte *first = frame() + get_page_size() - OFFSET_PAGE_DIR_ENTRY_COUNT;
1467 byte *ptr = first - (n * SIZE_OF_PAGE_DIR_ENTRY);
1468 return (ptr);
1469 }
1470
1472 byte *first = frame() + get_page_size() - OFFSET_PAGE_DIR_ENTRY_FIRST;
1473 byte *ptr = first - (frag_id * SIZE_OF_PAGE_DIR_ENTRY);
1474 return (mach_read_from_2(ptr));
1475 }
1476
1478 byte *first = frame() + get_page_size() - OFFSET_PAGE_DIR_ENTRY_FIRST;
1479 byte *ptr = first - (frag_id * SIZE_OF_PAGE_DIR_ENTRY);
1480 return (mach_read_from_2(ptr));
1481 }
1482
1483 void set_nth_dir_entry(ulint frag_id, paddr_t val) {
1484 byte *first = frame() + get_page_size() - OFFSET_PAGE_DIR_ENTRY_FIRST;
1485 byte *ptr = first - (frag_id * SIZE_OF_PAGE_DIR_ENTRY);
1487 }
1488
1491 set_nth_dir_entry(n - 1, 0);
1492 return (n - 1);
1493 }
1494
1495 void incr_n_dir_entries() const {
1497 ulint n = mach_read_from_2(ptr);
1498 ut_a(n < FRAG_ID_NULL);
1499 mlog_write_ulint(ptr, n + 1, MLOG_2BYTES, m_mtr);
1500 }
1501
1502 void decr_n_dir_entries() const {
1504 ulint n = mach_read_from_2(ptr);
1505 ut_a(n > 0);
1506 mlog_write_ulint(ptr, n - 1, MLOG_2BYTES, m_mtr);
1507 }
1508
1510 const page_size_t page_size = dict_table_page_size(m_index->table);
1511 return (page_size.physical());
1512 }
1513
1516 return (n * SIZE_OF_PAGE_DIR_ENTRY);
1517 }
1518
1521
1522 for (ulint frag_id = 0; frag_id < n; frag_id++) {
1523 ulint paddr = get_nth_dir_entry(frag_id);
1524
1525 if (paddr == 0) {
1526 return (frag_id);
1527 }
1528 }
1529
1530 return (FRAG_ID_NULL);
1531 }
1532
1533 /** Allocate a fragment id.
1534 @return On success, return fragment id.
1535 @return On failure, return FRAG_ID_NULL. */
1537 ulint id = locate_free_slot();
1538
1539 if (id == FRAG_ID_NULL) {
1540 return (alloc_dir_entry());
1541 }
1542
1543 return (id);
1544 }
1545
1546 std::ostream &print_frag_id(std::ostream &out) {
1548 out << "FRAG IDS: " << std::endl;
1549
1550 for (ulint frag_id = 0; frag_id < n; frag_id++) {
1551 out << "id=" << frag_id << ", addr=" << frag_id_to_addr(frag_id)
1552 << std::endl;
1553 }
1554
1555 return (out);
1556 }
1557
1558 /** Grow the frag directory by one entry.
1559 @return the fragment identifier that was newly added. */
1561
1562 /** Set the next page. */
1563 void set_page_next(page_no_t page_no) {
1565 }
1566
1567 /** Set the prev page. */
1568 void set_page_prev(page_no_t page_no) { set_page_prev(page_no, m_mtr); }
1569
1570 /** Set the prev page. */
1571 void set_page_prev(page_no_t page_no, mtr_t *mtr) {
1572 mlog_write_ulint(frame() + FIL_PAGE_PREV, page_no, MLOG_4BYTES, mtr);
1573 }
1574
1575 /** Get the next page number.
1576 @return next page number. */
1578
1579 /** Get the prev page number (FIL_PAGE_PREV).
1580 @param[in] mtr Mini-transaction latch context.
1581 @return prev page number. */
1583 return (mtr_read_ulint(frame() + FIL_PAGE_PREV, MLOG_4BYTES, mtr));
1584 }
1585
1586 /** Get the prev page number.
1587 @return prev page number. */
1589
1590 /** Allocate the fragment page.
1591 @param[in] first first page of this LOB.
1592 @param[in] hint hint page number for allocation.
1593 @param[in] bulk true if bulk operation (OPCODE_INSERT_BULK)
1594 false otherwise.
1595 @return the allocated buffer block. */
1596 buf_block_t *alloc(z_first_page_t &first, page_no_t hint, bool bulk);
1597
1598 /** Free the fragment page along with its entry.
1599 @param[in] first first page of LOB.
1600 @param[in] alloc_mtr mini trx to perform this modification. */
1601 void dealloc_with_entry(z_first_page_t &first, mtr_t *alloc_mtr);
1602
1603 /** Free the fragment page. */
1604 void dealloc() {
1606 m_block = nullptr;
1607 }
1608
1610 page_id_t page_id(dict_index_get_space(m_index), page_no);
1612 m_block =
1613 buf_page_get(page_id, page_size, RW_X_LATCH, UT_LOCATION_HERE, m_mtr);
1614 return (m_block);
1615 }
1616
1618 plist_base_node_t free_lst = free_list();
1619 frag_node_t frag(free_lst.get_first_node(), m_mtr);
1620 frag_node_t next = frag.get_next_frag();
1621
1622 while (!next.is_null() && frag.merge(next)) {
1623 free_lst.remove(next.m_node);
1624 next = frag.get_next_frag();
1625 }
1626 }
1627
1629 ut_ad(!frag.is_null());
1630 plist_base_node_t free_lst = free_list();
1631 frag_node_t next = frag.get_next_frag();
1632
1633 while (!next.is_null() && frag.merge(next)) {
1634 free_lst.remove(next.m_node);
1635 next = frag.get_next_frag();
1636 }
1637 }
1638
1639 bool validate_lists() const {
1640 plist_base_node_t free_lst = free_list();
1641 plist_base_node_t frag_lst = frag_list();
1642 plist_node_t free_node = free_lst.get_first_node();
1643
1644 while (!free_node.is_null()) {
1645 plist_node_t frag_node = frag_lst.get_first_node();
1646
1647 while (!frag_node.is_null()) {
1648 ut_ad(frag_node.addr() != free_node.addr());
1649 frag_node = frag_node.get_next_node();
1650 }
1651
1652 free_node = free_node.get_next_node();
1653 }
1654 return (true);
1655 }
1656
1658 ut_ad(frag.get_frag_id() == FRAG_ID_NULL);
1659
1660 plist_base_node_t free_lst = free_list();
1661
1662 plist_node_t node = free_lst.get_first_node();
1663 plist_node_t prev_node(m_mtr);
1664
1665 while (!node.is_null()) {
1666 ut_ad(frag.addr() != node.addr());
1667 if (frag.addr() < node.addr()) {
1668 break;
1669 }
1670 prev_node = node;
1671 node = node.get_next_node();
1672 }
1673
1674 free_lst.insert_before(node, frag.m_node);
1675
1676 if (prev_node.is_null()) {
1678 } else {
1679 frag_node_t prev_frag(prev_node, m_mtr);
1680 merge_free_frags(prev_frag);
1681 }
1682 }
1683
1684 /** Insert the given fragment node into the fragment list.
1685 @param[in,out] frag the fragment node to be inserted.*/
1687 plist_base_node_t frag_lst = frag_list();
1688 plist_node_t node = frag_lst.get_first_node();
1689
1690 while (!node.is_null()) {
1691 ut_ad(frag.addr() != node.addr());
1692 if (frag.addr() < node.addr()) {
1693 break;
1694 }
1695 node = node.get_next_node();
1696 }
1697
1698 frag_lst.insert_before(node, frag.m_node);
1699 }
1700
1701 /** Split one free fragment into two. This is not splitting a
1702 fragment page. This is just splitting one free fragment into two.
1703 When we want to allocate one fragment, we identify a big enough free
1704 fragment and split it into two - one will be the allocated portion and
1705 other will become a free fragment.
1706 @param[in] free_frag the free fragment that will be split.
1707 @param[in] size the payload size in bytes. */
1708 void split_free_frag(frag_node_t &free_frag, ulint size) {
1709 ut_ad(size < free_frag.payload());
1710 const ulint old_total_len = free_frag.get_total_len();
1711 plist_base_node_t free_lst = free_list();
1712
1713 /* Locate the next fragment */
1714 byte *p2 = free_frag.data_begin() + size;
1715
1716 ulint remain =
1717 free_frag.get_total_len() - frag_node_t::header_size() - size;
1718
1719 ut_a(remain >= frag_node_t::OFFSET_DATA);
1720
1721 free_frag.set_total_len(frag_node_t::header_size() + size);
1722
1723 frag_node_t frag2(frame(), p2, remain, m_mtr);
1724 frag2.set_total_len(remain);
1725 frag2.set_frag_id_null();
1726 free_lst.insert_after(free_frag.m_node, frag2.m_node);
1727
1728 ut_a(free_frag.get_total_len() + frag2.get_total_len() == old_total_len);
1729
1731 }
1732
1734 ut_ad(id != FRAG_ID_NULL);
1735
1736 paddr_t off = frag_id_to_addr(id);
1737 byte *f = frame();
1738 return (frag_node_t(f, f + off));
1739 }
1740
1741 void dealloc_fragment(ulint frag_id) {
1742 ut_ad(frag_id != FRAG_ID_NULL);
1743
1744 paddr_t off = frag_id_to_addr(frag_id);
1745 byte *f = frame();
1746 frag_node_t frag(f, f + off, m_mtr);
1747 dealloc_fragment(frag);
1748 dealloc_frag_id(frag_id);
1749
1750 /* Update the index entry. */
1752 }
1753
1754 /** Allocate a fragment with the given payload.
1755 @param[in] size the payload size.
1756 @param[in] entry the index entry of the given frag page.
1757 @return the frag_id of the allocated fragment.
1758 @return FRAG_ID_NULL if fragment could not be allocated. */
1760
1762 byte *f = frame();
1763 return (plist_base_node_t(f, f + OFFSET_FREE_LIST, m_mtr));
1764 }
1765
1767 byte *f = frame();
1768 return (plist_base_node_t(f, f + OFFSET_FRAGS_LIST, m_mtr));
1769 }
1770
1772 byte *ptr = frame() + FIL_PAGE_TYPE;
1774 }
1775
1777 return (mach_read_from_2(frame() + FIL_PAGE_TYPE));
1778 }
1779
1780 const char *get_page_type_str() const {
1783 return ("FIL_PAGE_TYPE_ZLOB_FRAG");
1784 }
1785
1786 /** The maximum free space available in a fragment page. Adjustment
1787 needs to be done with the frag_node_t::overhead().*/
1789
1790 /** The maximum free space available in a fragment page. Adjustment
1791 needs to be done with the frag_node_t::overhead().*/
1793 page_size_t page_size(dict_table_page_size(index->table));
1794 return (page_size.physical() - OFFSET_FRAGS_BEGIN -
1796 }
1797
1798 /** Determine if the given length of data can fit into a fragment
1799 page.
1800 @param[in] index the clust index into which LOB is inserted.
1801 @param[in] data_size The length of data to operate.
1802 @return true if data can fit into fragment page, false otherwise. */
1803 static bool can_data_fit(dict_index_t *index, ulint data_size);
1804
1805 /** Get the frag page number. */
1806 page_no_t get_page_no() const { return (m_block->get_page_no()); }
1807
1808 byte *frame() const { return (buf_block_get_frame(m_block)); }
1809
1810 std::ostream &print(std::ostream &out) const {
1811 print_free_list(out);
1812 print_frag_list(out);
1814 print_page_dir(out);
1815 return (out);
1816 }
1817
1818 /** Get the total amount of stored data in this page. */
1820
1821 /** Get the total cumulative free space in this page. */
1822 ulint get_total_free_len() const;
1823
1824 /** Get the big free space in this page. */
1825 ulint get_big_free_len() const;
1826
1827 /** Get the number of fragments in this frag page. */
1829 plist_base_node_t frag_lst = frag_list();
1830 return (frag_lst.get_len());
1831 }
1832
1833 std::ostream &print_frags_in_order(std::ostream &out) const;
1834
1835 std::ostream &print_free_list(std::ostream &out) const {
1836 if (m_block == nullptr) {
1837 return (out);
1838 }
1839
1840 plist_base_node_t free_lst = free_list();
1841 out << "[Free List: " << free_lst << "]" << std::endl;
1842
1843 for (plist_node_t cur = free_lst.get_first_node(); !cur.is_null();
1844 cur = cur.get_next_node()) {
1845 frag_node_t frag(cur, m_mtr);
1846 out << frag << std::endl;
1847 }
1848 return (out);
1849 }
1850
1851 std::ostream &print_frag_list(std::ostream &out) const {
1852 if (m_block == nullptr) {
1853 return (out);
1854 }
1855
1856 plist_base_node_t frag_lst = frag_list();
1857 out << "[Frag List: " << frag_lst << "]" << std::endl;
1858
1859 for (plist_node_t cur = frag_lst.get_first_node(); !cur.is_null();
1860 cur = cur.get_next_node()) {
1861 frag_node_t frag(cur, m_mtr);
1862 out << frag << std::endl;
1863 }
1864 return (out);
1865 }
1866
1867 std::ostream &print_page_dir(std::ostream &out) const {
1868 if (m_block == nullptr) {
1869 return (out);
1870 }
1871
1873
1874 for (ulint frag_id = 0; frag_id < n; ++frag_id) {
1875 paddr_t off = frag_id_to_addr(frag_id);
1876 out << "[frag_id=" << frag_id << ", addr=" << off << "]" << std::endl;
1877 }
1878
1879 return (out);
1880 }
1881
1882 void set_mtr(mtr_t *mtr) { m_mtr = mtr; }
1883
1884 void set_index(dict_index_t *index) { m_index = index; }
1885
1886 void set_block_null() { m_block = nullptr; }
1887
1888 /** Determine if the given fragment node is the last fragment
1889 node adjacent to the directory.
1890 @return true if it is last fragment node, false otherwise. */
1891 bool is_last_frag(const frag_node_t &node) const {
1892 return (node.end_ptr() == slots_end_ptr());
1893 }
1894
1895 private:
1898 }
1899
1901 plist_base_node_t frag_lst = frag_list();
1902 frag_lst.remove(frag.m_node);
1903 frag.set_frag_id_null();
1905 }
1906
1907 /** Deallocate all the free slots from the end of the page
1908 directory. */
1909 void dealloc_frag_id();
1910
1911 /** Deallocate the given fragment id.
1912 @param[in] frag_id The fragment that needs to be deallocated. */
1913 void dealloc_frag_id(ulint frag_id) {
1914 set_nth_dir_entry(frag_id, 0);
1916 }
1917
1921};
1922
1923/** Insert one chunk of input. The maximum size of a chunk is Z_CHUNK_SIZE.
1924@param[in] index Clustered index in which LOB is inserted.
1925@param[in] first First page of the LOB.
1926@param[in] trx Transaction doing the insertion.
1927@param[in] blob Uncompressed LOB to be inserted.
1928@param[in] len Length of the blob.
1929@param[out] out_entry Newly inserted index entry. can be NULL.
1930@param[in] mtr Mini-transaction
1931@param[in] bulk true if it is bulk operation, false otherwise.
1932@return DB_SUCCESS on success, error code on failure. */
1934 byte *blob, ulint len, z_index_entry_t *out_entry,
1935 mtr_t *mtr, bool bulk);
1936
1937} // namespace lob
1938
1939#endif // lob0impl_h
uint32_t space_id_t
Tablespace identifier.
Definition: api0api.h:46
uint32_t page_no_t
Page number.
Definition: api0api.h:44
Kerberos Client Authentication nullptr
Definition: auth_kerberos_client_plugin.cc:250
void btr_page_free_low(dict_index_t *index, buf_block_t *block, ulint level, mtr_t *mtr)
Frees a file page used in an index tree.
Definition: btr0btr.cc:553
The B-tree.
static buf_frame_t * buf_block_get_frame(const buf_block_t *block)
Gets a pointer to the memory frame of a block.
buf_block_t * buf_page_get(const page_id_t &id, const page_size_t &size, ulint latch, ut::Location location, mtr_t *mtr)
NOTE! The following macros should be used instead of buf_page_get_gen, to improve debugging.
Definition: buf0buf.h:440
The node of page list.
Definition: lob0impl.h:50
paddr_t addr() const
Obtain the offset of the page list node within the given page frame.
Definition: lob0impl.h:182
static const uint16_t OFFSET_PREV
Offset of the previous node.
Definition: lob0impl.h:53
void set_node(byte *node)
Set the page list node to the given value.
Definition: lob0impl.h:210
byte * m_frame
The page frame where this page list exists.
Definition: lob0impl.h:229
paddr_t get_prev() const
Get the offset of the previous page list node.
Definition: lob0impl.h:145
plist_node_t get_next_node() const
Get the next page list node.
Definition: lob0impl.h:153
void set_frame(byte *frame)
Set the page frame to the given value.
Definition: lob0impl.h:206
byte * get_frame() const
Get the page frame where this page list exists.
Definition: lob0impl.h:218
std::ostream & print(std::ostream &out) const
Print the page list node into the given output stream.
Definition: lob0impl.h:197
plist_node_t(const plist_node_t &other)=default
Copy constructor.
byte * ptr() const
Obtain the memory location of the page list node.
Definition: lob0impl.h:188
static const uint16_t OFFSET_NEXT
Offset of the next node.
Definition: lob0impl.h:56
void set_prev_node(plist_node_t &prev)
Set the previous page list node.
Definition: lob0impl.h:127
plist_node_t(byte *frame, byte *node)
Constructor.
Definition: lob0impl.h:78
bool is_equal(const plist_node_t &that) const
Definition: lob0impl.h:220
paddr_t get_next() const
Get the offset of the next page list node.
Definition: lob0impl.h:149
plist_node_t()
Default constructor.
Definition: lob0impl.h:67
void set_prev(paddr_t addr)
Set the offset of the previous node.
Definition: lob0impl.h:118
void set_mtr(mtr_t *mtr)
Set the mini-transaction context to the given value.
Definition: lob0impl.h:214
bool is_before(const plist_node_t &node) const
Check if the current node is before the given node in the page (w.r.t the offset).
Definition: lob0impl.h:100
bool is_null() const
Check if the given page list node is null.
Definition: lob0impl.h:192
void init()
Initialize the current page list node.
Definition: lob0impl.h:108
void set_next_node(const plist_node_t &next)
Set the next page list node.
Definition: lob0impl.h:141
plist_node_t(mtr_t *mtr)
Constructor.
Definition: lob0impl.h:63
mtr_t * m_mtr
The mini-transaction context.
Definition: lob0impl.h:235
void set_next(paddr_t addr)
Set the offset of the next node.
Definition: lob0impl.h:131
plist_node_t get_prev_node() const
Get the previous page list node.
Definition: lob0impl.h:167
static const uint8_t SIZE
The size of a page list node.
Definition: lob0impl.h:59
byte * m_node
The plist node is located at this address.
Definition: lob0impl.h:232
plist_node_t(byte *frame, byte *node, mtr_t *mtr)
Constructor.
Definition: lob0impl.h:87
plist_node_t(mtr_t *mtr, byte *frame)
Constructor.
Definition: lob0impl.h:72
plist_node_t & operator=(const plist_node_t &)=default
Page identifier.
Definition: buf0types.h:206
Page size descriptor.
Definition: page0size.h:49
size_t physical() const
Retrieve the physical page size (on-disk).
Definition: page0size.h:120
struct _entry entry
dberr_t
Definition: db0err.h:38
static const page_size_t dict_table_page_size(const dict_table_t *table)
Get the table page size.
static space_id_t dict_index_get_space(const dict_index_t *index)
Gets the space id of the root of the index tree.
fil_addr_t fil_addr_null
The null file address.
Definition: fil0fil.cc:325
constexpr page_type_t FIL_PAGE_TYPE_LOB_INDEX
Index pages of uncompressed LOB.
Definition: fil0fil.h:1289
uint16_t page_type_t
Definition: fil0fil.h:1208
constexpr page_type_t FIL_PAGE_TYPE_ZLOB_FRAG_ENTRY
Index pages of fragment pages (compressed LOB).
Definition: fil0fil.h:1311
constexpr page_no_t FIL_NULL
'null' (undefined) page offset in the context of file spaces
Definition: fil0fil.h:1146
constexpr page_type_t FIL_PAGE_TYPE_ZLOB_FRAG
Fragment pages of compressed LOB.
Definition: fil0fil.h:1308
constexpr page_type_t FIL_PAGE_TYPE_ZLOB_DATA
Data pages of compressed LOB.
Definition: fil0fil.h:1301
constexpr page_type_t FIL_PAGE_TYPE_ZLOB_INDEX
Index pages of compressed LOB.
Definition: fil0fil.h:1305
constexpr uint32_t FIL_PAGE_TYPE
file page type: FIL_PAGE_INDEX,..., 2 bytes.
Definition: fil0types.h:75
constexpr uint32_t FIL_PAGE_OFFSET
page offset inside space
Definition: fil0types.h:45
constexpr uint32_t FIL_PAGE_DATA
start of the data on the page
Definition: fil0types.h:110
constexpr size_t FIL_ADDR_SIZE
Address size is 6 bytes.
Definition: fil0types.h:127
constexpr uint32_t FIL_PAGE_SPACE_ID
alias for space id
Definition: fil0types.h:107
constexpr uint32_t FIL_PAGE_NEXT
if there is a 'natural' successor of the page, its offset.
Definition: fil0types.h:60
constexpr uint32_t FIL_PAGE_PREV
if there is a 'natural' predecessor of the page, its offset.
Definition: fil0types.h:50
constexpr uint32_t FIL_PAGE_DATA_END
size of the page trailer
Definition: fil0types.h:118
static byte * fut_get_ptr(space_id_t space, const page_size_t &page_size, fil_addr_t addr, rw_lock_type_t rw_latch, mtr_t *mtr, buf_block_t **ptr_block=nullptr)
Gets a pointer to a file address and latches the page.
void flst_add_last(flst_base_node_t *base, flst_node_t *node, mtr_t *mtr)
Adds a node as the last node in a list.
Definition: fut0lst.cc:89
void flst_remove(flst_base_node_t *base, flst_node_t *node2, mtr_t *mtr)
Removes a node.
Definition: fut0lst.cc:286
void flst_add_first(flst_base_node_t *base, flst_node_t *node, mtr_t *mtr)
Adds a node as the first node in a list.
Definition: fut0lst.cc:132
File-based list utilities.
static void flst_write_addr(fil_faddr_t *faddr, fil_addr_t addr, mtr_t *mtr)
Writes a file address.
byte flst_base_node_t
Definition: fut0lst.h:45
static fil_addr_t flst_read_addr(const fil_faddr_t *faddr, mtr_t *mtr)
Reads a file address.
byte flst_node_t
Definition: fut0lst.h:46
Implements the large objects (LOB) module.
Utilities for converting data from the database file to the machine format.
static uint16_t mach_read_from_2(const byte *b)
The following function is used to fetch data from 2 consecutive bytes.
static uint32_t mach_read_from_4(const byte *b)
The following function is used to fetch data from 4 consecutive bytes.
static void mach_write_to_6(byte *b, uint64_t id)
The following function is used to store data in 6 consecutive bytes.
Mini-transaction logging routines.
void mlog_log_string(byte *ptr, ulint len, mtr_t *mtr)
Logs a write of a string to a file page buffered in the buffer pool.
Definition: mtr0log.cc:344
void mlog_write_ulint(byte *ptr, ulint val, mlog_id_t type, mtr_t *mtr)
Writes 1, 2 or 4 bytes to a file page.
Definition: mtr0log.cc:255
Mini-transaction buffer.
#define mtr_read_ulint(p, t, m)
Read 1 - 4 bytes from a file page buffered in the buffer pool.
Definition: mtr0mtr.h:86
Mini-transaction buffer global types.
@ MLOG_4BYTES
4 bytes ...
Definition: mtr0types.h:75
@ MLOG_1BYTE
one byte is written
Definition: mtr0types.h:69
@ MLOG_2BYTES
2 bytes ...
Definition: mtr0types.h:72
constexpr value_type blob
Definition: classic_protocol_constants.h:271
PT & ref(PT *tp)
Definition: tablespace_impl.cc:358
Provides the large objects (LOB) module.
Definition: lob0del.h:31
dberr_t z_insert_chunk(dict_index_t *index, z_first_page_t &first, trx_t *trx, byte *blob, ulint len, z_index_entry_t *out_entry, mtr_t *mtr, bool bulk)
Insert one chunk of input.
Definition: lob0impl.cc:326
ulint paddr_t
Definition: lob0impl.h:46
ulint frag_id_t
Definition: lob0impl.h:488
const ulint KB16
Definition: lob0impl.h:490
dberr_t z_print_info(const dict_index_t *index, const lob::ref_t &ref, std::ostream &out)
Print information about the given compressed lob.
Definition: lob0impl.cc:533
const ulint FRAG_ID_NULL
Definition: lob0impl.h:489
std::ostream & operator<<(std::ostream &out, const plist_node_t &obj)
Definition: lob0impl.h:238
static page_t * page_align(const void *ptr)
Gets the start of a page.
byte page_t
Type of the index page.
Definition: page0types.h:151
struct result result
Definition: result.h:33
required string type
Definition: replication_group_member_actions.proto:33
Definition: completion_hash.h:34
The buffer control block structure.
Definition: buf0buf.h:1750
page_type_t get_page_type() const
Get the page type of the current buffer block.
Definition: buf0buf.h:1954
page_no_t get_next_page_no() const
Get the next page number of the current buffer block.
Definition: buf0buf.h:1942
page_no_t get_page_no() const
Get the page number of the current buffer block.
Definition: buf0buf.h:1938
Data structure for an index.
Definition: dict0mem.h:1045
dict_table_t * table
back pointer to table
Definition: dict0mem.h:1059
File space address.
Definition: fil0fil.h:1163
uint32_t boffset
Byte offset within the page.
Definition: fil0fil.h:1195
Definition: lob0util.h:41
mtr_t * m_mtr
Definition: lob0util.h:128
dict_index_t * m_index
Definition: lob0util.h:129
buf_block_t * m_block
Definition: lob0util.h:127
byte * frame() const
Definition: lob0util.h:98
The first page of an uncompressed LOB.
Definition: lob0first.h:42
The fragment node represents one fragment.
Definition: lob0impl.h:1136
frag_node_t get_next_frag()
Definition: lob0impl.h:1284
bool is_equal(const plist_node_t &node) const
Definition: lob0impl.h:1333
bool is_equal(const frag_node_t &that) const
Definition: lob0impl.h:1329
void set_total_len(ulint len)
Definition: lob0impl.h:1195
bool is_null() const
Definition: lob0impl.h:1327
ulint get_frag_id() const
Definition: lob0impl.h:1236
static ulint overhead()
Amount of space that will be used up by meta data.
Definition: lob0impl.h:1172
frag_node_t get_prev_node()
Definition: lob0impl.h:1292
static ulint header_size()
Only the header size.
Definition: lob0impl.h:1175
plist_node_t m_node
The page list node.
Definition: lob0impl.h:1338
byte * frag_begin() const
Definition: lob0impl.h:1191
byte * data_begin() const
Definition: lob0impl.h:1193
static const ulint OFFSET_LEN
The offset where the length of fragment is stored.
Definition: lob0impl.h:1139
frag_node_t get_next_node()
Definition: lob0impl.h:1290
frag_node_t(byte *frame, byte *ptr, mtr_t *mtr)
Constructor.
Definition: lob0impl.h:1165
byte * end_ptr() const
Gets the pointer just after the current fragment.
Definition: lob0impl.h:1264
bool merge(frag_node_t &next)
Merge the current fragment node with the given next fragment node.
Definition: lob0impl.h:1311
void decr_length_by_2()
Decrement the total length of this fragment by 2 bytes.
Definition: lob0impl.h:1211
void set_frag_id(ulint id)
Definition: lob0impl.h:1230
frag_node_t(const plist_node_t &node, mtr_t *mtr)
Constructor.
Definition: lob0impl.h:1154
frag_node_t get_prev_frag()
Definition: lob0impl.h:1294
frag_node_t(byte *frame, byte *ptr)
Definition: lob0impl.h:1157
static const ulint OFFSET_DATA
The offset where fragment data is stored.
Definition: lob0impl.h:1145
byte * ptr() const
Gets the pointer to the beginning of the current fragment.
Definition: lob0impl.h:1255
ulint payload() const
Get the space available in this fragment for storing data.
Definition: lob0impl.h:1241
bool is_before(const frag_node_t &frag) const
Definition: lob0impl.h:1219
static const ulint OFFSET_FRAG_ID
The offset where fragment id is stored.
Definition: lob0impl.h:1142
byte * frame() const
Get the page frame.
Definition: lob0impl.h:1271
paddr_t addr() const
Get the offset of the current fragment within page.
Definition: lob0impl.h:1250
mtr_t * m_mtr
The mini-transaction context.
Definition: lob0impl.h:1342
void set_frag_id_null()
Definition: lob0impl.h:1223
void incr_length_by_2()
Increment the total length of this fragment by 2 bytes.
Definition: lob0impl.h:1202
static const ulint SIZE_OF_PAGE_DIR_ENTRY
The size of a page directory entry in a fragment page in bytes.
Definition: lob0impl.h:1149
frag_node_t(byte *frame, byte *ptr, ulint len, mtr_t *mtr)
Constructor.
Definition: lob0impl.h:1184
std::ostream & print(std::ostream &out) const
Definition: lob0impl.h:1273
ulint get_total_len() const
Get the total length of this fragment, including its metadata.
Definition: lob0impl.h:1244
The node page (also can be called as the index page) contains a list of index_entry_t objects.
Definition: lob0impl.h:494
node_page_t(buf_block_t *block, mtr_t *mtr)
Definition: lob0impl.h:506
byte * nodes_begin() const
Definition: lob0impl.h:550
static const ulint OFFSET_VERSION
Version information.
Definition: lob0impl.h:496
static ulint payload()
Definition: lob0impl.h:535
static ulint max_space_available()
Definition: lob0impl.h:539
node_page_t()=default
Default ctor.
buf_block_t * alloc(first_page_t &first_page, bool bulk)
Allocate one node page.
Definition: lob0impl.cc:69
void set_version_0()
Definition: lob0impl.h:499
static const ulint LOB_PAGE_DATA
Definition: lob0impl.h:497
void set_page_type()
Definition: lob0impl.h:545
void dealloc()
Definition: lob0impl.h:530
buf_block_t * load_x(page_id_t page_id, page_size_t page_size)
Definition: lob0impl.h:524
node_page_t(buf_block_t *block, mtr_t *mtr, dict_index_t *index)
Definition: lob0impl.h:508
node_page_t(buf_block_t *block)
Constructor.
Definition: lob0impl.h:516
static ulint node_count()
Get the number of index entries this page can hold.
Definition: lob0impl.cc:1306
node_page_t(mtr_t *mtr, dict_index_t *index)
Definition: lob0impl.h:511
The base node of page list.
Definition: lob0impl.h:243
ulint get_len() const
Definition: lob0impl.h:385
void set_last(paddr_t addr)
Definition: lob0impl.h:442
void set_len(ulint len)
Definition: lob0impl.h:413
void add_to_empty(plist_node_t &node)
Definition: lob0impl.h:357
void decr_len()
Definition: lob0impl.h:426
bool empty() const
Definition: lob0impl.h:383
plist_node_t get_last_node() const
Definition: lob0impl.h:403
static const ulint SIZE
The total size (in bytes) of a page list base node.
Definition: lob0impl.h:257
void push_back(plist_node_t &node)
Definition: lob0impl.h:366
void incr_len()
Definition: lob0impl.h:419
paddr_t addr() const
Definition: lob0impl.h:453
void set_first(paddr_t addr)
Definition: lob0impl.h:436
paddr_t get_last() const
Definition: lob0impl.h:401
void insert_before(plist_node_t &node3, plist_node_t &node2)
Insert node2 before node3.
Definition: lob0impl.h:335
std::ostream & print_list(std::ostream &out) const
Definition: lob0impl.h:461
static const ulint OFFSET_LEN
The offset where the length of the page list is stored.
Definition: lob0impl.h:246
plist_base_node_t(byte *frame, byte *base, mtr_t *mtr)
Definition: lob0impl.h:259
std::ostream & print(std::ostream &out) const
Definition: lob0impl.h:455
bool validate() const
Validate the page list.
Definition: lob0impl.cc:53
void init()
Definition: lob0impl.h:262
plist_node_t get_first_node() const
Definition: lob0impl.h:391
void remove(plist_node_t &node)
Definition: lob0impl.h:270
mtr_t * m_mtr
Definition: lob0impl.h:480
byte * m_base
Definition: lob0impl.h:479
void insert_after(plist_node_t &node1, plist_node_t &node2)
Insert node2 after node1.
Definition: lob0impl.h:312
static const ulint OFFSET_FIRST
The offset where the first node is located.
Definition: lob0impl.h:250
byte * m_frame
Definition: lob0impl.h:478
void push_front(plist_node_t &node)
Definition: lob0impl.h:294
paddr_t get_first() const
Definition: lob0impl.h:387
static const ulint OFFSET_LAST
The offset where the last node is located.
Definition: lob0impl.h:254
plist_node_t get_node(paddr_t addr)
Definition: lob0impl.h:448
The struct 'lob::ref_t' represents an external field reference.
Definition: lob0lob.h:197
The data page holding the zlob.
Definition: lob0impl.h:891
static const ulint OFFSET_DATA_LEN
Definition: lob0impl.h:896
dict_index_t * m_index
Definition: lob0impl.h:1014
void set_data_len(ulint len)
Definition: lob0impl.h:974
fil_addr_t get_self_addr() const
Definition: lob0impl.h:1005
buf_block_t * alloc(page_no_t hint, bool bulk)
Allocate one data page.
Definition: lob0impl.cc:1275
void dealloc()
Free this data page holding the zlob data.
Definition: lob0impl.h:936
void set_version_0()
Definition: lob0impl.h:949
void set_trx_id_no_redo(trx_id_t tid)
Update the header with given transaction identifier, without writing redo log records.
Definition: lob0impl.h:995
byte * frame() const
Definition: lob0impl.h:1010
void set_trx_id(trx_id_t tid)
Definition: lob0impl.h:984
void set_next_page(page_no_t page_no)
Set the next page.
Definition: lob0impl.h:956
void set_page_type()
Set the correct page type.
Definition: lob0impl.h:942
static const ulint OFFSET_DATA_BEGIN
Definition: lob0impl.h:902
static const ulint OFFSET_VERSION
Version information.
Definition: lob0impl.h:893
ulint get_data_len() const
Definition: lob0impl.h:980
mtr_t * m_mtr
Definition: lob0impl.h:1013
z_data_page_t(buf_block_t *block)
Definition: lob0impl.h:917
static const ulint OFFSET_TRX_ID
Definition: lob0impl.h:899
page_no_t get_page_no() const
Get the page number.
Definition: lob0impl.h:1001
buf_block_t * m_block
Definition: lob0impl.h:1012
byte * begin_data_ptr() const
Definition: lob0impl.h:972
void set_space_id_no_redo(space_id_t space_id)
Write the space identifier to the page header, without generating redo log records.
Definition: lob0impl.h:923
z_data_page_t(mtr_t *mtr, dict_index_t *index)
Definition: lob0impl.h:909
ulint payload()
Definition: lob0impl.h:904
void init()
Definition: lob0impl.h:962
z_data_page_t(buf_block_t *block, mtr_t *mtr, dict_index_t *index)
Definition: lob0impl.h:912
The first page of an zlob.
Definition: zlob0first.h:37
An entry representing one fragment page.
Definition: lob0impl.h:554
static const ulint OFFSET_PREV
Offset within frag entry pointing to prev frag entry.
Definition: lob0impl.h:557
void set_big_free_len(ulint n)
Set the big free frag bytes.
Definition: lob0impl.h:752
ulint get_big_free_len() const
Get the biggest free frag bytes.
Definition: lob0impl.h:740
void reset(flst_node_t *node)
Point to another frag entry.
Definition: lob0impl.h:653
void remove(flst_base_node_t *bnode)
Remove this node from the given list.
Definition: lob0impl.h:629
void set_prev(const fil_addr_t &addr)
Set the previous frag entry as null.
Definition: lob0impl.h:663
void push_front(flst_base_node_t *bnode)
Add this node as the first node in the given list.
Definition: lob0impl.h:645
void init()
Initialize the fragment entry contents.
Definition: lob0impl.h:592
void free_frag_page(mtr_t *mtr, dict_index_t *index)
Free the fragment page pointed to by this entry.
Definition: lob0impl.cc:135
static const ulint OFFSET_N_FRAGS
Number of used fragments.
Definition: lob0impl.h:566
void set_null()
Set the current fragment entry to null.
Definition: lob0impl.h:606
z_frag_entry_t()
Constructor.
Definition: lob0impl.h:584
page_no_t get_page_no() const
Get the frag page number.
Definition: lob0impl.h:694
mtr_t * m_mtr
The mini-transaction context for operating on this fragment entry.
Definition: lob0impl.h:768
void purge(flst_base_node_t *used_lst, flst_base_node_t *free_lst)
Definition: lob0impl.cc:114
z_frag_entry_t(mtr_t *mtr)
Constructor.
Definition: lob0impl.h:587
void set_n_frags(ulint frags) const
Set the frag page number.
Definition: lob0impl.h:716
flst_node_t * m_node
The location where the fragment entry node is located.
Definition: lob0impl.h:764
static const ulint SIZE
Total size of one frag entry.
Definition: lob0impl.h:578
std::ostream & print(std::ostream &out) const
Definition: lob0impl.cc:105
ulint get_used_len() const
Get the used bytes.
Definition: lob0impl.h:723
static const ulint OFFSET_PAGE_NO
Offset within frag entry holding the page number of frag page.
Definition: lob0impl.h:563
void push_back(flst_base_node_t *bnode)
Add this node as the last node in the given list.
Definition: lob0impl.h:637
static const ulint OFFSET_NEXT
Offset within frag entry pointing to next frag entry.
Definition: lob0impl.h:560
static const ulint OFFSET_TOTAL_FREE_LEN
Total free space in bytes.
Definition: lob0impl.h:572
fil_addr_t get_self_addr() const
Definition: lob0impl.h:612
ulint get_n_frags() const
Get the frag page number.
Definition: lob0impl.h:711
void set_total_free_len(ulint n)
Set the total free bytes.
Definition: lob0impl.h:745
void set_prev_null()
Set the previous frag entry as null.
Definition: lob0impl.h:656
fil_addr_t get_next() const
Get the location of next frag entry.
Definition: lob0impl.h:689
void update(const z_frag_page_t &frag_page)
Update the current fragment entry with information about the given fragment page.
Definition: lob0impl.cc:125
z_frag_entry_t(flst_node_t *node, mtr_t *mtr)
Constructor.
Definition: lob0impl.h:581
ulint get_total_free_len() const
Get the total cumulative free bytes.
Definition: lob0impl.h:735
bool is_null() const
Check if the current fragment entry is null.
Definition: lob0impl.h:610
void set_next_null()
Set the next frag entry as null.
Definition: lob0impl.h:675
fil_addr_t get_prev() const
Get the location of previous frag entry.
Definition: lob0impl.h:670
static const ulint OFFSET_BIG_FREE_LEN
The biggest free frag space in bytes.
Definition: lob0impl.h:575
static const ulint OFFSET_USED_LEN
Used space in bytes.
Definition: lob0impl.h:569
void set_page_no(page_no_t page_no) const
Set the frag page number.
Definition: lob0impl.h:699
void set_used_len(ulint used) const
Set the used bytes.
Definition: lob0impl.h:728
void set_next(const fil_addr_t &addr)
Set the next frag entry.
Definition: lob0impl.h:682
A frag nodes page containing an array of z_frag_entry_t objects.
Definition: lob0impl.h:1018
z_frag_node_page_t(mtr_t *mtr, dict_index_t *index)
Definition: lob0impl.h:1023
mtr_t * m_mtr
The mini-transaction context.
Definition: lob0impl.h:1121
void set_version_0()
Definition: lob0impl.h:1054
buf_block_t * load_x(page_no_t page_no)
Load the given compressed LOB fragment page.
Definition: lob0impl.h:1082
static const ulint LOB_PAGE_DATA
Definition: lob0impl.h:1021
void init(flst_base_node_t *free_lst)
Definition: lob0impl.h:1093
buf_block_t * alloc(z_first_page_t &first, bool bulk)
Allocate a fragment nodes page.
Definition: lob0impl.cc:617
static const ulint OFFSET_VERSION
Version information.
Definition: lob0impl.h:1020
void dealloc()
Definition: lob0impl.h:1074
void set_space_id_no_redo(space_id_t space_id)
Write the space identifier to the page header, without generating redo log records.
Definition: lob0impl.h:1034
buf_block_t * m_block
The buffer block of the fragment page.
Definition: lob0impl.h:1118
void set_next_page_no(page_no_t page_no)
Set the next page number.
Definition: lob0impl.h:1048
z_frag_node_page_t(buf_block_t *block)
Constructor.
Definition: lob0impl.h:1028
page_no_t get_next_page_no() const
Get the next page number.
Definition: lob0impl.h:1066
byte * frame() const
Definition: lob0impl.h:1115
ulint get_n_frag_entries() const
Definition: lob0impl.h:1111
void set_page_type()
Set the correct page type.
Definition: lob0impl.h:1040
page_no_t get_page_no() const
Get the page number.
Definition: lob0impl.h:1061
ulint payload() const
Definition: lob0impl.h:1106
dict_index_t * m_index
The index to which the LOB belongs.
Definition: lob0impl.h:1124
The fragment page.
Definition: lob0impl.h:1351
const char * get_page_type_str() const
Definition: lob0impl.h:1780
fil_addr_t get_frag_entry_addr() const
Definition: lob0impl.h:1896
z_frag_page_t(mtr_t *mtr, dict_index_t *index)
Constructor.
Definition: lob0impl.h:1391
static const ulint OFFSET_FRAG_ENTRY
The location of z_frag_entry_t for this page.
Definition: lob0impl.h:1356
void dealloc_with_entry(z_first_page_t &first, mtr_t *alloc_mtr)
Free the fragment page along with its entry.
Definition: lob0impl.cc:759
ulint space_used_by_dir() const
Definition: lob0impl.h:1514
byte * frame() const
Definition: lob0impl.h:1808
std::ostream & print(std::ostream &out) const
Definition: lob0impl.h:1810
page_no_t get_next_page_no() const
Get the next page number.
Definition: lob0impl.h:1577
void set_page_next(page_no_t page_no)
Set the next page.
Definition: lob0impl.h:1563
std::ostream & print_frags_in_order(std::ostream &out) const
Definition: lob0impl.cc:802
flst_node_t * addr2ptr_x(fil_addr_t &addr)
Definition: lob0impl.h:1422
bool validate_lists() const
Definition: lob0impl.h:1639
buf_block_t * m_block
Definition: lob0impl.h:1918
ulint payload()
The maximum free space available in a fragment page.
Definition: lob0impl.h:1788
static const ulint OFFSET_FRAGS_BEGIN
The offset within page where the fragments can occupy .
Definition: lob0impl.h:1366
paddr_t frag_id_to_addr(ulint frag_id) const
Definition: lob0impl.h:1471
ulint get_total_free_len() const
Get the total cumulative free space in this page.
Definition: lob0impl.cc:861
static const ulint SIZE_OF_PAGE_DIR_ENTRY
Definition: lob0impl.h:1376
std::ostream & print_frag_id(std::ostream &out)
Definition: lob0impl.h:1546
z_frag_page_t(buf_block_t *block, mtr_t *mtr, dict_index_t *index)
Constructor.
Definition: lob0impl.h:1382
std::ostream & print_frag_list(std::ostream &out) const
Definition: lob0impl.h:1851
static const ulint OFFSET_FREE_LIST
The offset within page where the free space list begins.
Definition: lob0impl.h:1359
static const ulint OFFSET_PAGE_DIR_ENTRY_FIRST
Offset of first page directory entry (from end)
Definition: lob0impl.h:1373
dict_index_t * m_index
Definition: lob0impl.h:1920
void set_mtr(mtr_t *mtr)
Definition: lob0impl.h:1882
void dealloc_frag_id(ulint frag_id)
Deallocate the given fragment id.
Definition: lob0impl.h:1913
static ulint max_payload(dict_index_t *index)
The maximum free space available in a fragment page.
Definition: lob0impl.h:1792
void incr_n_dir_entries() const
Definition: lob0impl.h:1495
plist_base_node_t free_list() const
Definition: lob0impl.h:1761
ulint get_nth_dir_entry(ulint frag_id)
Definition: lob0impl.h:1477
void dealloc_fragment(ulint frag_id)
Definition: lob0impl.h:1741
z_frag_page_t(buf_block_t *block)
Constructor.
Definition: lob0impl.h:1396
plist_base_node_t frag_list() const
Definition: lob0impl.h:1766
static const ulint OFFSET_FRAGS_LIST
The offset within page where the fragment list begins.
Definition: lob0impl.h:1362
void set_page_type()
Definition: lob0impl.h:1771
void insert_into_free_list(frag_node_t &frag)
Definition: lob0impl.h:1657
bool is_last_frag(const frag_node_t &node) const
Determine if the given fragment node is the last fragment node adjacent to the directory.
Definition: lob0impl.h:1891
buf_block_t * alloc(z_first_page_t &first, page_no_t hint, bool bulk)
Allocate the fragment page.
Definition: lob0impl.cc:544
static const ulint OFFSET_PAGE_DIR_ENTRY_COUNT
Offset of number of page directory entries (from end)
Definition: lob0impl.h:1370
page_no_t get_prev_page_no() const
Get the prev page number.
Definition: lob0impl.h:1588
void dealloc_fragment(frag_node_t &frag)
Definition: lob0impl.h:1900
ulint get_page_size() const
Definition: lob0impl.h:1509
static bool can_data_fit(dict_index_t *index, ulint data_size)
Determine if the given length of data can fit into a fragment page.
Definition: lob0impl.cc:609
void decr_n_dir_entries() const
Definition: lob0impl.h:1502
byte * slots_end_ptr() const
Definition: lob0impl.h:1464
void set_version_0()
Definition: lob0impl.h:1418
ulint alloc_dir_entry()
Grow the frag directory by one entry.
Definition: lob0impl.cc:720
void set_block_null()
Definition: lob0impl.h:1886
void merge_free_frags()
Definition: lob0impl.h:1617
ulint alloc_frag_id()
Allocate a fragment id.
Definition: lob0impl.h:1536
void set_page_prev(page_no_t page_no, mtr_t *mtr)
Set the prev page.
Definition: lob0impl.h:1571
ulint get_n_frags() const
Get the number of fragments in this frag page.
Definition: lob0impl.h:1828
void set_n_dir_entries(ulint n) const
Definition: lob0impl.h:1455
std::ostream & print_free_list(std::ostream &out) const
Definition: lob0impl.h:1835
void set_index(dict_index_t *index)
Definition: lob0impl.h:1884
static const ulint OFFSET_VERSION
Version information.
Definition: lob0impl.h:1353
std::ostream & print_page_dir(std::ostream &out) const
Definition: lob0impl.h:1867
frag_node_t get_frag_node(frag_id_t id) const
Definition: lob0impl.h:1733
mtr_t * m_mtr
Definition: lob0impl.h:1919
ulint locate_free_slot()
Definition: lob0impl.h:1519
void insert_into_frag_list(frag_node_t &frag)
Insert the given fragment node into the fragment list.
Definition: lob0impl.h:1686
z_frag_entry_t get_frag_entry_x()
Definition: lob0impl.cc:743
page_no_t get_page_no() const
Get the frag page number.
Definition: lob0impl.h:1806
page_type_t get_page_type() const
Definition: lob0impl.h:1776
frag_id_t alloc_fragment(ulint size, z_frag_entry_t &entry)
Allocate a fragment with the given payload.
Definition: lob0impl.cc:642
void set_frag_entry_null() const
Definition: lob0impl.h:1446
ulint get_n_dir_entries() const
Definition: lob0impl.h:1450
void update_frag_entry()
Definition: lob0impl.h:1413
void set_space_id_no_redo(space_id_t space_id)
Write the space identifier to the page header, without generating redo log records.
Definition: lob0impl.h:1405
flst_node_t * addr2ptr_s(fil_addr_t &addr)
Definition: lob0impl.h:1428
ulint init_last_dir_entry()
Definition: lob0impl.h:1489
bool is_border_frag(const frag_node_t &node) const
Definition: lob0impl.h:1460
void split_free_frag(frag_node_t &free_frag, ulint size)
Split one free fragment into two.
Definition: lob0impl.h:1708
fil_addr_t get_frag_entry() const
Obtain the file address of the fragment entry that denotes the current fragment page.
Definition: lob0impl.h:1442
ulint get_big_free_len() const
Get the big free space in this page.
Definition: lob0impl.cc:876
ulint get_total_stored_data() const
Get the total amount of stored data in this page.
Definition: lob0impl.cc:844
void dealloc()
Free the fragment page.
Definition: lob0impl.h:1604
void set_page_prev(page_no_t page_no)
Set the prev page.
Definition: lob0impl.h:1568
void set_nth_dir_entry(ulint frag_id, paddr_t val)
Definition: lob0impl.h:1483
buf_block_t * load_x(page_no_t page_no)
Definition: lob0impl.h:1609
z_frag_entry_t get_frag_entry_s()
Definition: lob0impl.cc:751
void set_frag_entry(const fil_addr_t &addr) const
Definition: lob0impl.h:1434
page_no_t get_prev_page_no(mtr_t *mtr) const
Get the prev page number (FIL_PAGE_PREV).
Definition: lob0impl.h:1582
void dealloc_frag_id()
Deallocate all the free slots from the end of the page directory.
Definition: lob0impl.cc:898
void merge_free_frags(frag_node_t &frag)
Definition: lob0impl.h:1628
An index entry pointing to one zlib stream.
Definition: zlob0index.h:86
An index page containing an array of z_index_entry_t objects.
Definition: lob0impl.h:776
buf_block_t * m_block
The buffer block of the compressed LOB index page.
Definition: lob0impl.h:881
void init(flst_base_node_t *free_lst, mtr_t *mtr)
Definition: lob0impl.cc:1291
z_index_page_t(buf_block_t *block)
Constructor.
Definition: lob0impl.h:800
void set_space_id_no_redo(space_id_t space_id)
Write the space identifier to the page header, without generating redo log records.
Definition: lob0impl.h:812
static const ulint OFFSET_VERSION
Version information.
Definition: lob0impl.h:778
void dealloc()
Definition: lob0impl.h:863
page_no_t get_page_no() const
Get the page number.
Definition: lob0impl.h:835
z_index_page_t(mtr_t *mtr)
Constructor.
Definition: lob0impl.h:783
void set_next_page_no(page_no_t page_no)
Set the next page number.
Definition: lob0impl.h:828
void set_version_0()
Definition: lob0impl.h:823
static const ulint LOB_PAGE_DATA
Definition: lob0impl.h:779
page_no_t get_next_page_no() const
Get the next page number.
Definition: lob0impl.h:840
dict_index_t * m_index
The index to which the LOB belongs.
Definition: lob0impl.h:887
buf_block_t * alloc(z_first_page_t &first, bool bulk)
Allocate an ZLOB index page.
Definition: lob0impl.cc:1245
mtr_t * m_mtr
The mini-transaction context.
Definition: lob0impl.h:884
z_index_page_t(buf_block_t *block, dict_index_t *index)
Constructor.
Definition: lob0impl.h:806
ulint payload() const
Definition: lob0impl.h:870
ulint get_n_index_entries() const
Definition: lob0impl.cc:1302
z_index_page_t(mtr_t *mtr, dict_index_t *index)
Constructor.
Definition: lob0impl.h:795
z_index_page_t(buf_block_t *block, mtr_t *mtr, dict_index_t *index)
Constructor.
Definition: lob0impl.h:789
void set_page_type(mtr_t *mtr)
Set the correct page type.
Definition: lob0impl.h:818
buf_block_t * load_x(page_no_t page_no)
Load the given compressed LOB index page.
Definition: lob0impl.h:853
byte * frame() const
Definition: lob0impl.h:878
Mini-transaction handle and buffer.
Definition: mtr0mtr.h:176
Definition: result.h:29
Definition: trx0trx.h:683
@ RW_X_LATCH
Definition: sync0rw.h:98
@ RW_S_LATCH
Definition: sync0rw.h:97
ib_id_t trx_id_t
Transaction identifier (DB_TRX_ID, DATA_TRX_ID)
Definition: trx0types.h:137
#define UNIV_PAGE_SIZE
The universal page size of the database.
Definition: univ.i:293
unsigned long int ulint
Definition: univ.i:405
constexpr ulint ULINT_UNDEFINED
The 'undefined' value for a ulint.
Definition: univ.i:419
#define UT_LOCATION_HERE
Definition: ut0core.h:72
#define ut_ad(EXPR)
Debug assertion.
Definition: ut0dbg.h:104
#define ut_a(EXPR)
Abort execution if EXPR does not evaluate to nonzero.
Definition: ut0dbg.h:92
int n
Definition: xcom_base.cc:508