Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
Postgres FD Implementation
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Abuhujair Javed
Postgres FD Implementation
Commits
420cbff8
Commit
420cbff8
authored
May 19, 2006
by
Teodor Sigaev
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Simplify gistSplit() and some refactoring related code.
parent
49b3462a
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
168 additions
and
203 deletions
+168
-203
src/backend/access/gist/gist.c
src/backend/access/gist/gist.c
+42
-103
src/backend/access/gist/gistutil.c
src/backend/access/gist/gistutil.c
+105
-80
src/backend/access/gist/gistxlog.c
src/backend/access/gist/gistxlog.c
+5
-17
src/include/access/gist_private.h
src/include/access/gist_private.h
+16
-3
No files found.
src/backend/access/gist/gist.c
View file @
420cbff8
...
...
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/gist/gist.c,v 1.13
5 2006/05/17 16:34:59
teodor Exp $
* $PostgreSQL: pgsql/src/backend/access/gist/gist.c,v 1.13
6 2006/05/19 16:15:17
teodor Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -936,31 +936,6 @@ gistmakedeal(GISTInsertState *state, GISTSTATE *giststate)
gistxlogInsertCompletion
(
state
->
r
->
rd_node
,
&
(
state
->
key
),
1
);
}
static
void
gistToRealOffset
(
OffsetNumber
*
arr
,
int
len
,
OffsetNumber
*
reasloffset
)
{
int
i
;
for
(
i
=
0
;
i
<
len
;
i
++
)
arr
[
i
]
=
reasloffset
[
arr
[
i
]];
}
static
IndexTupleData
*
gistfillitupvec
(
IndexTuple
*
vec
,
int
veclen
,
int
*
memlen
)
{
char
*
ptr
,
*
ret
=
palloc
(
BLCKSZ
);
int
i
;
ptr
=
ret
;
for
(
i
=
0
;
i
<
veclen
;
i
++
)
{
memcpy
(
ptr
,
vec
[
i
],
IndexTupleSize
(
vec
[
i
]));
ptr
+=
IndexTupleSize
(
vec
[
i
]);
}
*
memlen
=
ptr
-
ret
;
Assert
(
*
memlen
<
BLCKSZ
);
return
(
IndexTupleData
*
)
ret
;
}
/*
* gistSplit -- split a page in the tree.
*/
...
...
@@ -975,100 +950,70 @@ gistSplit(Relation r,
*
rvectup
;
GIST_SPLITVEC
v
;
GistEntryVector
*
entryvec
;
int
i
,
fakeoffset
;
OffsetNumber
*
realoffset
;
IndexTuple
*
cleaneditup
=
itup
;
int
lencleaneditup
=
len
;
int
i
;
OffsetNumber
offInvTuples
[
MaxOffsetNumber
];
int
nOffInvTuples
=
0
;
SplitedPageLayout
*
res
=
NULL
;
/* generate the item array */
realoffset
=
palloc
((
len
+
1
)
*
sizeof
(
OffsetNumber
));
entryvec
=
palloc
(
GEVHDRSZ
+
(
len
+
1
)
*
sizeof
(
GISTENTRY
));
entryvec
->
n
=
len
+
1
;
fakeoffset
=
FirstOffsetNumber
;
for
(
i
=
1
;
i
<=
len
;
i
++
)
{
Datum
datum
;
bool
IsNull
;
if
(
!
GistPageIsLeaf
(
page
)
&&
GistTupleIsInvalid
(
itup
[
i
-
1
]))
{
entryvec
->
n
--
;
/* remember position of invalid tuple */
realoffset
[
entryvec
->
n
]
=
i
;
offInvTuples
[
nOffInvTuples
++
]
=
i
;
if
(
nOffInvTuples
>
0
)
/* we can safely do not decompress other keys, because
we will do splecial processing, but
it's needed to find another invalid tuples */
continue
;
}
datum
=
index_getattr
(
itup
[
i
-
1
],
1
,
giststate
->
tupdesc
,
&
IsNull
);
gistdentryinit
(
giststate
,
0
,
&
(
entryvec
->
vector
[
fakeoffset
]),
gistdentryinit
(
giststate
,
0
,
&
(
entryvec
->
vector
[
i
]),
datum
,
r
,
page
,
i
,
ATTSIZE
(
datum
,
giststate
->
tupdesc
,
1
,
IsNull
),
FALSE
,
IsNull
);
realoffset
[
fakeoffset
]
=
i
;
fakeoffset
++
;
}
/*
* if it was invalid tuple then we need special processing. If it's
* possible, we move all invalid tuples on right page. We should remember,
* that union with invalid tuples is a invalid tuple.
* if it was invalid tuple then we need special processing.
* We move all invalid tuples on right page.
*
* if there is no place on left page, gistSplit will be called one more
* time for left page.
*
* Normally, we never exec this code, but after crash replay it's possible
* to get 'invalid' tuples (probability is low enough)
*/
if
(
entryvec
->
n
!=
len
+
1
)
if
(
nOffInvTuples
>
0
)
{
lencleaneditup
=
entryvec
->
n
-
1
;
cleaneditup
=
(
IndexTuple
*
)
palloc
(
lencleaneditup
*
sizeof
(
IndexTuple
));
for
(
i
=
1
;
i
<
entryvec
->
n
;
i
++
)
cleaneditup
[
i
-
1
]
=
itup
[
realoffset
[
i
]
-
1
];
GistSplitVec
gsvp
;
if
(
!
gistfitpage
(
cleaneditup
,
lencleaneditup
))
{
/* no space on left to put all good tuples, so picksplit */
gistUserPicksplit
(
r
,
entryvec
,
&
v
,
cleaneditup
,
lencleaneditup
,
giststate
);
v
.
spl_leftvalid
=
true
;
v
.
spl_right
=
offInvTuples
;
v
.
spl_nright
=
nOffInvTuples
;
v
.
spl_rightvalid
=
false
;
gistToRealOffset
(
v
.
spl_left
,
v
.
spl_nleft
,
realoffset
);
gistToRealOffset
(
v
.
spl_right
,
v
.
spl_nright
,
realoffset
);
}
else
{
/* we can try to store all valid tuples on one page */
v
.
spl_right
=
(
OffsetNumber
*
)
palloc
(
entryvec
->
n
*
sizeof
(
OffsetNumber
));
v
.
spl_left
=
(
OffsetNumber
*
)
palloc
(
entryvec
->
n
*
sizeof
(
OffsetNumber
));
if
(
lencleaneditup
==
0
)
{
/* all tuples are invalid, so moves half of its to right */
v
.
spl_leftvalid
=
v
.
spl_rightvalid
=
false
;
v
.
spl_nright
=
0
;
v
.
spl_left
=
(
OffsetNumber
*
)
palloc
(
entryvec
->
n
*
sizeof
(
OffsetNumber
));
v
.
spl_nleft
=
0
;
for
(
i
=
1
;
i
<=
len
;
i
++
)
if
(
i
-
1
<
len
/
2
)
v
.
spl_left
[
v
.
spl_nleft
++
]
=
i
;
else
v
.
spl_right
[
v
.
spl_nright
++
]
=
i
;
}
else
{
/*
* we will not call gistUserPicksplit, just put good tuples on
* left and invalid on right
*/
v
.
spl_nleft
=
lencleaneditup
;
v
.
spl_nright
=
0
;
for
(
i
=
1
;
i
<
entryvec
->
n
;
i
++
)
v
.
spl_left
[
i
-
1
]
=
i
;
gistToRealOffset
(
v
.
spl_left
,
v
.
spl_nleft
,
realoffset
);
v
.
spl_lattr
[
0
]
=
v
.
spl_ldatum
=
(
Datum
)
0
;
v
.
spl_rattr
[
0
]
=
v
.
spl_rdatum
=
(
Datum
)
0
;
v
.
spl_lisnull
[
0
]
=
true
;
v
.
spl_risnull
[
0
]
=
true
;
gistunionsubkey
(
r
,
giststate
,
itup
,
&
v
,
true
);
for
(
i
=
1
;
i
<=
len
;
i
++
)
if
(
!
GistTupleIsInvalid
(
itup
[
i
-
1
])
)
v
.
spl_left
[
v
.
spl_nleft
++
]
=
i
;
v
.
spl_leftvalid
=
true
;
v
.
spl_rightvalid
=
false
;
}
}
gsvp
.
idgrp
=
NULL
;
gsvp
.
attrsize
=
v
.
spl_lattrsize
;
gsvp
.
attr
=
v
.
spl_lattr
;
gsvp
.
len
=
v
.
spl_nleft
;
gsvp
.
entries
=
v
.
spl_left
;
gsvp
.
isnull
=
v
.
spl_lisnull
;
gistunionsubkeyvec
(
giststate
,
itup
,
&
gsvp
,
true
);
}
else
{
...
...
@@ -1088,12 +1033,6 @@ gistSplit(Relation r,
for
(
i
=
0
;
i
<
v
.
spl_nright
;
i
++
)
rvectup
[
i
]
=
itup
[
v
.
spl_right
[
i
]
-
1
];
/* place invalid tuples on right page if itsn't done yet */
for
(
fakeoffset
=
entryvec
->
n
;
fakeoffset
<
len
+
1
&&
lencleaneditup
;
fakeoffset
++
)
{
rvectup
[
v
.
spl_nright
++
]
=
itup
[
realoffset
[
fakeoffset
]
-
1
];
}
/* finalyze splitting (may need another split) */
if
(
!
gistfitpage
(
rvectup
,
v
.
spl_nright
))
{
...
...
src/backend/access/gist/gistutil.c
View file @
420cbff8
...
...
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/gist/gistutil.c,v 1.1
2 2006/05/17 16:34:59
teodor Exp $
* $PostgreSQL: pgsql/src/backend/access/gist/gistutil.c,v 1.1
3 2006/05/19 16:15:17
teodor Exp $
*-------------------------------------------------------------------------
*/
#include "postgres.h"
...
...
@@ -139,6 +139,30 @@ gistjoinvector(IndexTuple *itvec, int *len, IndexTuple *additvec, int addlen)
return
itvec
;
}
/*
* make plain IndexTupleVector
*/
IndexTupleData
*
gistfillitupvec
(
IndexTuple
*
vec
,
int
veclen
,
int
*
memlen
)
{
char
*
ptr
,
*
ret
;
int
i
;
*
memlen
=
0
;
for
(
i
=
0
;
i
<
veclen
;
i
++
)
*
memlen
+=
IndexTupleSize
(
vec
[
i
]);
ptr
=
ret
=
palloc
(
*
memlen
);
for
(
i
=
0
;
i
<
veclen
;
i
++
)
{
memcpy
(
ptr
,
vec
[
i
],
IndexTupleSize
(
vec
[
i
]));
ptr
+=
IndexTupleSize
(
vec
[
i
]);
}
return
(
IndexTupleData
*
)
ret
;
}
/*
* Return an IndexTuple containing the result of applying the "union"
* method to the specified IndexTuple vector.
...
...
@@ -314,40 +338,14 @@ gistgetadjusted(Relation r, IndexTuple oldtup, IndexTuple addtup, GISTSTATE *gis
}
void
gistunionsubkey
(
Relation
r
,
GISTSTATE
*
giststate
,
IndexTuple
*
itvec
,
GIST_SPLITVEC
*
spl
,
bool
isall
)
{
int
lr
;
for
(
lr
=
0
;
lr
<
2
;
lr
++
)
{
OffsetNumber
*
entries
;
gistunionsubkeyvec
(
GISTSTATE
*
giststate
,
IndexTuple
*
itvec
,
GistSplitVec
*
gsvp
,
bool
isall
)
{
int
i
;
Datum
*
attr
;
int
len
,
*
attrsize
;
bool
*
isnull
;
GistEntryVector
*
evec
;
if
(
lr
)
{
attrsize
=
spl
->
spl_lattrsize
;
attr
=
spl
->
spl_lattr
;
len
=
spl
->
spl_nleft
;
entries
=
spl
->
spl_left
;
isnull
=
spl
->
spl_lisnull
;
}
else
{
attrsize
=
spl
->
spl_rattrsize
;
attr
=
spl
->
spl_rattr
;
len
=
spl
->
spl_nright
;
entries
=
spl
->
spl_right
;
isnull
=
spl
->
spl_risnull
;
}
evec
=
palloc
(((
len
<
2
)
?
2
:
len
)
*
sizeof
(
GISTENTRY
)
+
GEVHDRSZ
);
evec
=
palloc
(((
gsvp
->
len
<
2
)
?
2
:
gsvp
->
len
)
*
sizeof
(
GISTENTRY
)
+
GEVHDRSZ
);
for
(
i
=
(
isall
)
?
0
:
1
;
i
<
r
->
rd_att
->
natts
;
i
++
)
for
(
i
=
(
isall
)
?
0
:
1
;
i
<
giststate
->
tupdesc
->
natts
;
i
++
)
{
int
j
;
Datum
datum
;
...
...
@@ -355,13 +353,14 @@ gistunionsubkey(Relation r, GISTSTATE *giststate, IndexTuple *itvec, GIST_SPLITV
int
real_len
;
real_len
=
0
;
for
(
j
=
0
;
j
<
len
;
j
++
)
for
(
j
=
0
;
j
<
gsvp
->
len
;
j
++
)
{
bool
IsNull
;
if
(
spl
->
spl_idgrp
[
entries
[
j
]])
if
(
gsvp
->
idgrp
&&
gsvp
->
idgrp
[
gsvp
->
entries
[
j
]])
continue
;
datum
=
index_getattr
(
itvec
[
entries
[
j
]
-
1
],
i
+
1
,
datum
=
index_getattr
(
itvec
[
gsvp
->
entries
[
j
]
-
1
],
i
+
1
,
giststate
->
tupdesc
,
&
IsNull
);
if
(
IsNull
)
continue
;
...
...
@@ -379,7 +378,7 @@ gistunionsubkey(Relation r, GISTSTATE *giststate, IndexTuple *itvec, GIST_SPLITV
{
datum
=
(
Datum
)
0
;
datumsize
=
0
;
isnull
[
i
]
=
true
;
gsvp
->
isnull
[
i
]
=
true
;
}
else
{
...
...
@@ -398,15 +397,41 @@ gistunionsubkey(Relation r, GISTSTATE *giststate, IndexTuple *itvec, GIST_SPLITV
datum
=
FunctionCall2
(
&
giststate
->
unionFn
[
i
],
PointerGetDatum
(
evec
),
PointerGetDatum
(
&
datumsize
));
isnull
[
i
]
=
false
;
gsvp
->
isnull
[
i
]
=
false
;
}
attr
[
i
]
=
datum
;
attrsize
[
i
]
=
datumsize
;
}
gsvp
->
attr
[
i
]
=
datum
;
gsvp
->
attrsize
[
i
]
=
datumsize
;
}
}
/*
* unions subkey for after user picksplit over first column
*/
static
void
gistunionsubkey
(
GISTSTATE
*
giststate
,
IndexTuple
*
itvec
,
GIST_SPLITVEC
*
spl
)
{
GistSplitVec
gsvp
;
gsvp
.
idgrp
=
spl
->
spl_idgrp
;
gsvp
.
attrsize
=
spl
->
spl_lattrsize
;
gsvp
.
attr
=
spl
->
spl_lattr
;
gsvp
.
len
=
spl
->
spl_nleft
;
gsvp
.
entries
=
spl
->
spl_left
;
gsvp
.
isnull
=
spl
->
spl_lisnull
;
gistunionsubkeyvec
(
giststate
,
itvec
,
&
gsvp
,
false
);
gsvp
.
attrsize
=
spl
->
spl_rattrsize
;
gsvp
.
attr
=
spl
->
spl_rattr
;
gsvp
.
len
=
spl
->
spl_nright
;
gsvp
.
entries
=
spl
->
spl_right
;
gsvp
.
isnull
=
spl
->
spl_risnull
;
gistunionsubkeyvec
(
giststate
,
itvec
,
&
gsvp
,
false
);
}
/*
* find group in vector with equal value
*/
...
...
@@ -840,7 +865,7 @@ gistUserPicksplit(Relation r, GistEntryVector *entryvec, GIST_SPLITVEC *v,
* if index is multikey, then we must to try get smaller bounding box for
* subkey(s)
*/
if
(
r
->
rd_att
->
natts
>
1
)
if
(
giststate
->
tupdesc
->
natts
>
1
)
{
int
MaxGrpId
;
...
...
@@ -851,7 +876,7 @@ gistUserPicksplit(Relation r, GistEntryVector *entryvec, GIST_SPLITVEC *v,
MaxGrpId
=
gistfindgroup
(
giststate
,
entryvec
->
vector
,
v
);
/* form union of sub keys for each page (l,p) */
gistunionsubkey
(
r
,
giststate
,
itup
,
v
,
false
);
gistunionsubkey
(
giststate
,
itup
,
v
);
/*
* if possible, we insert equivalent tuples with control by penalty
...
...
src/backend/access/gist/gistxlog.c
View file @
420cbff8
...
...
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/gist/gistxlog.c,v 1.1
8 2006/05/19 11:10:25
teodor Exp $
* $PostgreSQL: pgsql/src/backend/access/gist/gistxlog.c,v 1.1
9 2006/05/19 16:15:17
teodor Exp $
*-------------------------------------------------------------------------
*/
#include "postgres.h"
...
...
@@ -557,28 +557,16 @@ gistMakePageLayout(Buffer *buffers, int nbuffers) {
while
(
nbuffers
--
>
0
)
{
Page
page
=
BufferGetPage
(
buffers
[
nbuffers
]
);
IndexTuple
idxtup
;
OffsetNumber
i
;
char
*
ptr
;
IndexTuple
*
vec
;
int
veclen
;
resptr
=
(
SplitedPageLayout
*
)
palloc0
(
sizeof
(
SplitedPageLayout
)
);
resptr
->
block
.
blkno
=
BufferGetBlockNumber
(
buffers
[
nbuffers
]
);
resptr
->
block
.
num
=
PageGetMaxOffsetNumber
(
page
);
for
(
i
=
FirstOffsetNumber
;
i
<=
PageGetMaxOffsetNumber
(
page
);
i
++
)
{
idxtup
=
(
IndexTuple
)
PageGetItem
(
page
,
PageGetItemId
(
page
,
i
));
resptr
->
lenlist
+=
IndexTupleSize
(
idxtup
);
}
resptr
->
list
=
(
IndexTupleData
*
)
palloc
(
resptr
->
lenlist
);
ptr
=
(
char
*
)(
resptr
->
list
);
for
(
i
=
FirstOffsetNumber
;
i
<=
PageGetMaxOffsetNumber
(
page
);
i
++
)
{
idxtup
=
(
IndexTuple
)
PageGetItem
(
page
,
PageGetItemId
(
page
,
i
));
memcpy
(
ptr
,
idxtup
,
IndexTupleSize
(
idxtup
)
);
ptr
+=
IndexTupleSize
(
idxtup
);
}
vec
=
gistextractpage
(
page
,
&
veclen
);
resptr
->
list
=
gistfillitupvec
(
vec
,
veclen
,
&
(
resptr
->
lenlist
)
);
resptr
->
next
=
res
;
res
=
resptr
;
...
...
src/include/access/gist_private.h
View file @
420cbff8
...
...
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/access/gist_private.h,v 1.1
4 2006/05/17 16:34:59
teodor Exp $
* $PostgreSQL: pgsql/src/include/access/gist_private.h,v 1.1
5 2006/05/19 16:15:17
teodor Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -283,6 +283,8 @@ extern IndexTuple *gistextractpage(Page page, int *len /* out */ );
extern
IndexTuple
*
gistjoinvector
(
IndexTuple
*
itvec
,
int
*
len
,
IndexTuple
*
additvec
,
int
addlen
);
extern
IndexTupleData
*
gistfillitupvec
(
IndexTuple
*
vec
,
int
veclen
,
int
*
memlen
);
extern
IndexTuple
gistunion
(
Relation
r
,
IndexTuple
*
itvec
,
int
len
,
GISTSTATE
*
giststate
);
extern
IndexTuple
gistgetadjusted
(
Relation
r
,
...
...
@@ -308,8 +310,19 @@ extern void gistcentryinit(GISTSTATE *giststate, int nkey,
extern
void
gistDeCompressAtt
(
GISTSTATE
*
giststate
,
Relation
r
,
IndexTuple
tuple
,
Page
p
,
OffsetNumber
o
,
GISTENTRY
*
attdata
,
bool
*
isnull
);
extern
void
gistunionsubkey
(
Relation
r
,
GISTSTATE
*
giststate
,
IndexTuple
*
itvec
,
GIST_SPLITVEC
*
spl
,
bool
isall
);
typedef
struct
{
int
*
attrsize
;
Datum
*
attr
;
int
len
;
OffsetNumber
*
entries
;
bool
*
isnull
;
int
*
idgrp
;
}
GistSplitVec
;
extern
void
gistunionsubkeyvec
(
GISTSTATE
*
giststate
,
IndexTuple
*
itvec
,
GistSplitVec
*
gsvp
,
bool
isall
);
extern
void
GISTInitBuffer
(
Buffer
b
,
uint32
f
);
extern
void
gistdentryinit
(
GISTSTATE
*
giststate
,
int
nkey
,
GISTENTRY
*
e
,
Datum
k
,
Relation
r
,
Page
pg
,
OffsetNumber
o
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment