Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit fa58d72

Browse files
committed
Merge branch 'PGPROEE10' into PGPROEE10_wait_sampling
2 parents 9b97e23 + 4e15936 commit fa58d72

20 files changed

+1439
-11365
lines changed

contrib/in_memory/Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ submake-isolation:
4141
submake-in_memory:
4242
$(MAKE) -C $(top_builddir)/contrib/in_memory
4343

44-
REGRESSCHECKS = in_memory tuple_limit subtrans ddl_forbid non_coercible
44+
REGRESSCHECKS = in_memory tuple_limit subtrans ddl_forbid non_coercible collation
4545

4646
regresscheck: | submake-regress submake-in_memory temp-install
4747
$(pg_regress_check) \
@@ -60,5 +60,5 @@ isolationcheck: | submake-isolation submake-in_memory temp-install
6060

6161
temp-install: EXTRA_INSTALL=contrib/in_memory
6262

63-
standby-check: submake-in_memory temp-install
63+
prove-check: submake-in_memory temp-install
6464
$(prove_check)

contrib/in_memory/btree.c

Lines changed: 187 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@
2626
#include "btree_private.h"
2727
#include "fdw.h"
2828

29+
static int get_split_item_size(Page p, OffsetNumber newoffset,
30+
LocationIndex newitem_size, bool replace, OffsetNumber offset);
31+
static OffsetNumber find_split_location(Page p, OffsetNumber offset,
32+
LocationIndex tuplesize, bool replace, float target_ratio);
2933
static PageNumber btree_split(BTreeDescr *desc, Page p, OffsetNumber *offset,
3034
bool *place_right, Pointer tupleheader, Pointer tuple,
3135
OffsetNumber tuplesize, bool replace, uint32 *state, CommitSeqNo *csn);
@@ -54,6 +58,117 @@ init_btree(BTreeDescr *desc)
5458
init_meta_page(GET_PAGE(desc->meta), 1);
5559
}
5660

61+
/*
62+
* Get size of item during split consideration.
63+
*/
64+
static int
65+
get_split_item_size(Page p, OffsetNumber newoffset, LocationIndex newitem_size,
66+
bool replace, OffsetNumber offset)
67+
{
68+
if (offset < newoffset)
69+
return BTREE_PAGE_GET_ITEM_SIZE(p, offset) + sizeof(OffsetNumber);
70+
else if (offset == newoffset)
71+
return newitem_size + sizeof(OffsetNumber);
72+
else if (replace)
73+
return BTREE_PAGE_GET_ITEM_SIZE(p, offset) + sizeof(OffsetNumber);
74+
else
75+
return BTREE_PAGE_GET_ITEM_SIZE(p, offset - 1) + sizeof(OffsetNumber);
76+
}
77+
78+
/*
79+
* Find appropriate location to split. Return number of tuples to be placed
80+
* to the left page.
81+
*/
82+
static OffsetNumber
83+
find_split_location(Page p, OffsetNumber offset, LocationIndex tuplesize,
84+
bool replace, float target_ratio)
85+
{
86+
int left_free_space;
87+
int right_free_space;
88+
int left_bound;
89+
int right_bound;
90+
int first_data_key = BTREE_FIRST_DATA_KEY(p);
91+
int count;
92+
bool left_bounded = false;
93+
bool right_bounded = false;
94+
bool leaf = PAGE_IS_LEAF(p);
95+
LocationIndex header_size = leaf ? OLeafTupleHeaderSize : OInternalTupleHeaderSize;
96+
LocationIndex newitem_size = sizeof(OffsetNumber) + header_size + tuplesize;
97+
LocationIndex item_size;
98+
99+
/*
100+
* Covert ratio of fillfactor to ratio of free space.
101+
*/
102+
target_ratio = target_ratio / (1.0 - target_ratio);
103+
104+
count = BTREE_PAGE_ITEMS_COUNT(p) - first_data_key + (replace ? 0 : 1);
105+
left_free_space = right_free_space = IN_MEMORY_BLCKSZ - offsetof(BTreePageHeader, items);
106+
107+
/*
108+
* Left and right pages initially contain one item each. Left page also
109+
* reserves space for high key. For leafs, We assume that high key
110+
* couldn't be wider than than source tuple.
111+
*/
112+
left_bound = 1;
113+
left_free_space -= get_split_item_size(p, offset, newitem_size,
114+
replace, first_data_key);
115+
left_free_space -= get_split_item_size(p, offset, newitem_size,
116+
replace, first_data_key + 1);
117+
118+
right_bound = count - 1;
119+
right_free_space -= get_split_item_size(p, offset, newitem_size,
120+
replace, first_data_key + count - 1);
121+
if (!PAGE_IS_RIGHTMOST(p))
122+
right_free_space -= BTREE_PAGE_GET_ITEM_SIZE(p, BTREE_HIKEY) + sizeof(OffsetNumber);
123+
124+
Assert(left_free_space >= 0 && right_free_space >= 0);
125+
126+
/*
127+
* Iterate shifting left bound upper and right bound lower until those
128+
* bounds meet each other.
129+
*/
130+
while (left_bound < right_bound)
131+
{
132+
if (right_bounded || (!left_bounded &&
133+
(float) left_free_space * target_ratio > (float) right_free_space))
134+
{
135+
Assert(!left_bounded);
136+
item_size = get_split_item_size(p, offset, newitem_size, replace,
137+
first_data_key + left_bound + 1);
138+
if (left_free_space >= item_size)
139+
{
140+
left_free_space -= item_size;
141+
left_bound++;
142+
}
143+
else
144+
{
145+
left_bounded = true;
146+
}
147+
}
148+
else
149+
{
150+
Assert(!right_bounded);
151+
item_size = get_split_item_size(p, offset, newitem_size, replace,
152+
first_data_key + right_bound - 1);
153+
if (right_free_space >= item_size)
154+
{
155+
right_free_space -= item_size;
156+
right_bound--;
157+
}
158+
else
159+
{
160+
right_bounded = true;
161+
}
162+
}
163+
}
164+
165+
Assert(left_bound == right_bound);
166+
return left_bound;
167+
}
168+
169+
/*
170+
* Split B-tree page into two.
171+
*/
57172
static PageNumber
58173
btree_split(BTreeDescr *desc, Page p, OffsetNumber *offset, bool *place_right,
59174
Pointer tupleheader, Pointer tuple, LocationIndex tuplesize,
@@ -85,7 +200,10 @@ btree_split(BTreeDescr *desc, Page p, OffsetNumber *offset, bool *place_right,
85200
{
86201
right_count = count / 2;
87202
}
88-
left_count = (count - right_count) + BTREE_FIRST_DATA_KEY(p);
203+
left_count = find_split_location(p, *offset, tuplesize, replace,
204+
was_rightmost ? 0.9 : 0.5);
205+
right_count = count - left_count;
206+
left_count += BTREE_FIRST_DATA_KEY(p);
89207
if (*offset < left_count)
90208
{
91209
*place_right = false;
@@ -162,33 +280,26 @@ btree_split(BTreeDescr *desc, Page p, OffsetNumber *offset, bool *place_right,
162280
new_header->csn = *csn;
163281
new_header->undoPos = undo_pos;
164282

165-
/* Insert tuple */
283+
/* Insert new tuple to the right page if needed */
166284
if (*place_right)
167285
{
168286
if (!replace)
169-
add_page_item(new_page, *offset, tuplesize + header_size);
287+
add_page_item(new_page, *offset, MAXALIGN(tuplesize) + header_size);
170288
else
171-
resize_page_item(new_page, *offset, tuplesize + header_size);
289+
resize_page_item(new_page, *offset, MAXALIGN(tuplesize) + header_size);
172290
tuple_ptr = BTREE_PAGE_GET_ITEM(new_page, *offset);
291+
memcpy(tuple_ptr, tupleheader, header_size);
292+
tuple_ptr += header_size;
293+
memcpy(tuple_ptr, tuple, tuplesize);
173294
}
174-
else
175-
{
176-
if (!replace)
177-
add_page_item(p, *offset, tuplesize + header_size);
178-
else
179-
resize_page_item(p, *offset, tuplesize + header_size);
180-
tuple_ptr = BTREE_PAGE_GET_ITEM(p, *offset);
181-
}
182-
memcpy(tuple_ptr, tupleheader, header_size);
183-
tuple_ptr += header_size;
184-
memcpy(tuple_ptr, tuple, tuplesize);
185295

296+
/* Update high key of left page */
186297
first_data_key = BTREE_FIRST_DATA_KEY(new_page);
187298
rightbound_key = BTREE_PAGE_GET_ITEM(new_page, first_data_key) + header_size;
188299
if (leaf)
189300
{
190301
rightbound_key = desc->tuple_make_key(desc, rightbound_key);
191-
rightbound_key_size = MAXALIGN(desc->key_len(desc, rightbound_key));
302+
rightbound_key_size = desc->key_len(desc, rightbound_key);
192303
}
193304
else
194305
{
@@ -197,13 +308,33 @@ btree_split(BTreeDescr *desc, Page p, OffsetNumber *offset, bool *place_right,
197308
}
198309

199310
if (was_rightmost)
200-
add_page_item(p, BTREE_HIKEY, rightbound_key_size);
311+
{
312+
if (!(*place_right))
313+
(*offset)++;
314+
add_page_item(p, BTREE_HIKEY, MAXALIGN(rightbound_key_size));
315+
}
201316
else
202-
resize_page_item(p, BTREE_HIKEY, rightbound_key_size);
317+
{
318+
resize_page_item(p, BTREE_HIKEY, MAXALIGN(rightbound_key_size));
319+
}
203320

204321
memcpy(BTREE_PAGE_GET_ITEM(p, BTREE_HIKEY),
205322
rightbound_key, rightbound_key_size);
206323

324+
/* Insert new tuple to the left page if needed */
325+
if (!(*place_right))
326+
{
327+
if (!replace)
328+
add_page_item(p, *offset, MAXALIGN(tuplesize) + header_size);
329+
else
330+
resize_page_item(p, *offset, MAXALIGN(tuplesize) + header_size);
331+
tuple_ptr = BTREE_PAGE_GET_ITEM(p, *offset);
332+
memcpy(tuple_ptr, tupleheader, header_size);
333+
tuple_ptr += header_size;
334+
memcpy(tuple_ptr, tuple, tuplesize);
335+
}
336+
337+
207338
#ifdef NOT_USED
208339
/* Remove leftmost key from the page */
209340
if (!leaf)
@@ -275,7 +406,8 @@ insert_to_leaf(BTreeStack *stack,
275406

276407
while (true)
277408
{
278-
PageFitsItemResult fit = page_fits_item(p, offset, tuplen + tupheaderlen, replace);
409+
LocationIndex itemsize = MAXALIGN(tuplen) + tupheaderlen;
410+
PageFitsItemResult fit = page_fits_item(p, offset, itemsize, replace);
279411

280412
if (fit != PageNotFit)
281413
{
@@ -286,26 +418,49 @@ insert_to_leaf(BTreeStack *stack,
286418
{
287419
compact_page(desc, p, &state);
288420
offset = btree_page_binary_search(desc, p, tuple, BTreeTuple);
421+
422+
/*
423+
* If we were going to replace the tuple, then we should check
424+
* it's not gone after compaction.
425+
*/
426+
if (replace)
427+
{
428+
Assert(PAGE_IS_LEAF(p)); /* We place tuples only on leaf pages */
429+
430+
if (offset < header->itemsCount)
431+
{
432+
Pointer curTuple = BTREE_PAGE_GET_ITEM(p, offset) +
433+
OLeafTupleHeaderSize;
434+
if (desc->cmp(desc, tuple, BTreeTuple, curTuple, BTreeTuple))
435+
replace = false;
436+
}
437+
else
438+
{
439+
replace = false;
440+
}
441+
}
289442
}
290443

291444
state = modify_page(p, state);
292445
if (!replace)
293446
{
294-
add_page_item(p, offset, tuplen + tupheaderlen);
447+
add_page_item(p, offset, itemsize);
295448

296449
/* Increment number of tuples in progress */
297450
if (level == 0)
298451
header->nInProgress++;
299452
}
300453
else
301454
{
455+
int old_item_size = BTREE_PAGE_GET_ITEM_SIZE(p, offset);
456+
302457
/*
303458
* We should be able to undo this action without memory
304459
* allocation. Thus we shouldn't cut space occupied by this
305460
* page item.
306461
*/
307-
if (tuplen + tupheaderlen > BTREE_PAGE_GET_ITEM_SIZE(p, offset))
308-
resize_page_item(p, offset, tuplen + tupheaderlen);
462+
if (itemsize > old_item_size)
463+
resize_page_item(p, offset, itemsize);
309464

310465
if (level == 0)
311466
{
@@ -324,8 +479,8 @@ insert_to_leaf(BTreeStack *stack,
324479
* tuple.
325480
*/
326481
if (prev->deleted)
327-
header->nVacatedBytes -= BTREE_PAGE_GET_ITEM_SIZE(p, offset)
328-
+ sizeof(OffsetNumber);
482+
header->nVacatedBytes -= (old_item_size
483+
+ sizeof(OffsetNumber));
329484
}
330485
}
331486
}
@@ -656,6 +811,7 @@ btree_modify_internal(BTreeDescr *desc, BTreeModifyAction action,
656811
}
657812

658813
undo_pos = preserve_undo_record(OLeafTupleHeaderSize);
814+
659815
if (!UndoPosIsValid(undo_pos))
660816
{
661817
unlock_page(p, state);
@@ -697,6 +853,12 @@ btree_modify_internal(BTreeDescr *desc, BTreeModifyAction action,
697853
{
698854
/* If we deleted it ourselves, revert this deletion */
699855
apply_undo(desc, p, offset, false);
856+
857+
/*
858+
* We've already reverted the previous delete, so don't
859+
* consider it as sefl update anymore.
860+
*/
861+
self_update = NoSelfUpdate;
700862
}
701863
replace = true;
702864
}
@@ -747,7 +909,7 @@ btree_modify_internal(BTreeDescr *desc, BTreeModifyAction action,
747909
}
748910
}
749911

750-
tuplen = MAXALIGN(desc->tuple_len(desc, tuple));
912+
tuplen = desc->tuple_len(desc, tuple);
751913
insert_to_leaf(&stack, tuple, tuplen, &leaf_header, replace, self_update, undo_pos);
752914

753915
return result;

0 commit comments

Comments
 (0)