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