1/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2// vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4:
3#ident "$Id$"
4/*======
5This file is part of PerconaFT.
6
7
8Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
9
10 PerconaFT is free software: you can redistribute it and/or modify
11 it under the terms of the GNU General Public License, version 2,
12 as published by the Free Software Foundation.
13
14 PerconaFT is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with PerconaFT. If not, see <http://www.gnu.org/licenses/>.
21
22----------------------------------------
23
24 PerconaFT is free software: you can redistribute it and/or modify
25 it under the terms of the GNU Affero General Public License, version 3,
26 as published by the Free Software Foundation.
27
28 PerconaFT is distributed in the hope that it will be useful,
29 but WITHOUT ANY WARRANTY; without even the implied warranty of
30 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31 GNU Affero General Public License for more details.
32
33 You should have received a copy of the GNU Affero General Public License
34 along with PerconaFT. If not, see <http://www.gnu.org/licenses/>.
35======= */
36
37#ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved."
38
39#pragma once
40
41#define flt_flush_before_applying_inbox 1
42#define flt_flush_before_child_pin 2
43#define ft_flush_aflter_child_pin 3
44#define flt_flush_before_split 4
45#define flt_flush_during_split 5
46#define flt_flush_before_merge 6
47#define ft_flush_aflter_merge 7
48#define ft_flush_aflter_rebalance 8
49#define flt_flush_before_unpin_remove 9
50#define flt_flush_before_pin_second_node_for_merge 10
51
52typedef struct flusher_advice FLUSHER_ADVICE;
53
54/**
55 * Choose a child to flush to. Returns a childnum, or -1 if we should
56 * go no further.
57 *
58 * Flusher threads: pick the heaviest child buffer
59 * Cleaner threads: pick the heaviest child buffer
60 * Cleaner thread merging leaf nodes: follow down to a key
61 * Hot optimize table: follow down to the right of a key
62 */
63typedef int (*FA_PICK_CHILD)(FT ft, FTNODE parent, void* extra);
64
65/**
66 * Decide whether to call `toku_ft_flush_some_child` on the child if it is
67 * stable and a nonleaf node.
68 *
69 * Flusher threads: yes if child is gorged
70 * Cleaner threads: yes if child is gorged
71 * Cleaner thread merging leaf nodes: always yes
72 * Hot optimize table: always yes
73 */
74typedef bool (*FA_SHOULD_RECURSIVELY_FLUSH)(FTNODE child, void* extra);
75
76/**
77 * Called if the child needs merging. Should do something to get the
78 * child out of a fusible state. Must unpin parent and child.
79 *
80 * Flusher threads: just do the merge
81 * Cleaner threads: if nonleaf, just merge, otherwise start a "cleaner
82 * thread merge"
83 * Cleaner thread merging leaf nodes: just do the merge
84 * Hot optimize table: just do the merge
85 */
86typedef void (*FA_MAYBE_MERGE_CHILD)(struct flusher_advice *fa,
87 FT ft,
88 FTNODE parent,
89 int childnum,
90 FTNODE child,
91 void* extra);
92
93/**
94 * Cleaner threads may need to destroy basement nodes which have been
95 * brought more up to date than the height 1 node flushing to them.
96 * This function is used to determine if we need to check for basement
97 * nodes that are too up to date, and then destroy them if we find
98 * them.
99 *
100 * Flusher threads: no
101 * Cleaner threads: yes
102 * Cleaner thread merging leaf nodes: no
103 * Hot optimize table: no
104 */
105typedef bool (*FA_SHOULD_DESTROY_BN)(void* extra);
106
107/**
108 * Update `ft_flusher_status` in whatever way necessary. Called once
109 * by `toku_ft_flush_some_child` right before choosing what to do next (split,
110 * merge, recurse), with the number of nodes that were dirtied by this
111 * execution of `toku_ft_flush_some_child`.
112 */
113typedef void (*FA_UPDATE_STATUS)(FTNODE child, int dirtied, void* extra);
114
115/**
116 * Choose whether to go to the left or right child after a split. Called
117 * by `ft_split_child`. If -1 is returned, `ft_split_child` defaults to
118 * the old behavior.
119 */
120typedef int (*FA_PICK_CHILD_AFTER_SPLIT)(FT ft,
121 FTNODE node,
122 int childnuma,
123 int childnumb,
124 void* extra);
125
126/**
127 * A collection of callbacks used by the flushing machinery to make
128 * various decisions. There are implementations of each of these
129 * functions for flusher threads (flt_*), cleaner threads (ct_*), , and hot
130 * optimize table (hot_*).
131 */
132struct flusher_advice {
133 FA_PICK_CHILD pick_child;
134 FA_SHOULD_RECURSIVELY_FLUSH should_recursively_flush;
135 FA_MAYBE_MERGE_CHILD maybe_merge_child;
136 FA_SHOULD_DESTROY_BN should_destroy_basement_nodes;
137 FA_UPDATE_STATUS update_status;
138 FA_PICK_CHILD_AFTER_SPLIT pick_child_after_split;
139 void* extra; // parameter passed into callbacks
140};
141
142void
143flusher_advice_init(
144 struct flusher_advice *fa,
145 FA_PICK_CHILD pick_child,
146 FA_SHOULD_DESTROY_BN should_destroy_basement_nodes,
147 FA_SHOULD_RECURSIVELY_FLUSH should_recursively_flush,
148 FA_MAYBE_MERGE_CHILD maybe_merge_child,
149 FA_UPDATE_STATUS update_status,
150 FA_PICK_CHILD_AFTER_SPLIT pick_child_after_split,
151 void* extra
152 );
153
154void toku_ft_flush_some_child(
155 FT ft,
156 FTNODE parent,
157 struct flusher_advice *fa
158 );
159
160bool
161always_recursively_flush(FTNODE child, void* extra);
162
163bool
164never_recursively_flush(FTNODE UU(child), void* UU(extra));
165
166bool
167dont_destroy_basement_nodes(void* extra);
168
169void
170default_merge_child(struct flusher_advice *fa,
171 FT ft,
172 FTNODE parent,
173 int childnum,
174 FTNODE child,
175 void* extra);
176
177int
178default_pick_child_after_split(FT ft,
179 FTNODE parent,
180 int childnuma,
181 int childnumb,
182 void *extra);
183
184