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 /*======
5 This file is part of PerconaFT.
6 
7 
8 Copyright (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 
52 typedef 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  */
63 typedef 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  */
74 typedef 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  */
86 typedef 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  */
105 typedef 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  */
113 typedef 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  */
120 typedef 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  */
132 struct 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 
142 void
143 flusher_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 
154 void toku_ft_flush_some_child(
155     FT ft,
156     FTNODE parent,
157     struct flusher_advice *fa
158     );
159 
160 bool
161 always_recursively_flush(FTNODE child, void* extra);
162 
163 bool
164 never_recursively_flush(FTNODE UU(child), void* UU(extra));
165 
166 bool
167 dont_destroy_basement_nodes(void* extra);
168 
169 void
170 default_merge_child(struct flusher_advice *fa,
171                     FT ft,
172                     FTNODE parent,
173                     int childnum,
174                     FTNODE child,
175                     void* extra);
176 
177 int
178 default_pick_child_after_split(FT ft,
179                                FTNODE parent,
180                                int childnuma,
181                                int childnumb,
182                                void *extra);
183 
184