Lists: | pgsql-hackers |
---|
From: | Victor Drobny <v(dot)drobny(at)postgrespro(dot)ru> |
---|---|
To: | Pgsql Hackers <pgsql-hackers(at)postgresql(dot)org> |
Subject: | Red-Black tree traversal tests |
Date: | 2017-07-28 17:39:37 |
Message-ID: | [email protected] |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Lists: | pgsql-hackers |
Hello,
Postgres now has its own red-black tree implementation. This tree has 4
types of traversals. In the attachment, you can find module test that
checks the correctness of tree traversal strategies.
I hope that someone can find it useful.
Thank you for attention!
--
------
Victor Drobny
Postgres Professional: http://www.postgrespro.com
The Russian Postgres Company
Attachment | Content-Type | Size |
---|---|---|
rbtree_test.patch | text/x-diff | 15.7 KB |
From: | Aleksander Alekseev <a(dot)alekseev(at)postgrespro(dot)ru> |
---|---|
To: | Victor Drobny <v(dot)drobny(at)postgrespro(dot)ru> |
Cc: | Pgsql Hackers <pgsql-hackers(at)postgresql(dot)org> |
Subject: | Re: Red-Black tree traversal tests |
Date: | 2017-08-01 09:54:47 |
Message-ID: | [email protected] |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Lists: | pgsql-hackers |
Hi Victor,
> Postgres now has its own red-black tree implementation. This tree has 4
> types of traversals. In the attachment, you can find module test that
> checks the correctness of tree traversal strategies.
>
> I hope that someone can find it useful.
Great job! However, according to lcov report, some procedures declared
in rbtree.c are still not test covered even with your patch,
particularly:
* rb_find
* rb_leftmost
* rb_delete + dependencies (rb_delete_fixup, etc)
You can generate a corresponding report using this script [1].
I must say, I was a little surprised that rb_find is not used anywhere
in PostgreSQL code. Turned out that rbtree currently is used only by GIN
and it uses a small subset of all procedures.
If it's not too much trouble perhaps you could write a few more test so
we would have 100% test coverage for rbtree, could modify it safely and
be sure that it actually works when someone will need the rest of its
functionality?
[1]: https://github.com/afiskon/pgscripts/blob/master/code-coverage.sh
--
Best regards,
Aleksander Alekseev
From: | Aleksander Alekseev <a(dot)alekseev(at)postgrespro(dot)ru> |
---|---|
To: | Victor Drobny <v(dot)drobny(at)postgrespro(dot)ru> |
Cc: | Pgsql Hackers <pgsql-hackers(at)postgresql(dot)org> |
Subject: | Re: Red-Black tree traversal tests |
Date: | 2017-08-01 09:58:36 |
Message-ID: | [email protected] |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Lists: | pgsql-hackers |
Hi Victor,
> If it's not too much trouble perhaps you could write a few more test so
> we would have 100% test coverage for rbtree, could modify it safely and
> be sure that it actually works when someone will need the rest of its
> functionality?
Also I would recommend to add your patch to the nearest commitfest [1].
Otherwise there is a good chance that everyone will forget about it
quite soon.
[1]: https://commitfest.postgresql.org/14/
--
Best regards,
Aleksander Alekseev
From: | Victor Drobny <v(dot)drobny(at)postgrespro(dot)ru> |
---|---|
To: | Aleksander Alekseev <a(dot)alekseev(at)postgrespro(dot)ru> |
Cc: | Pgsql Hackers <pgsql-hackers(at)postgresql(dot)org> |
Subject: | Re: Red-Black tree traversal tests |
Date: | 2017-08-02 12:13:04 |
Message-ID: | [email protected] |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Lists: | pgsql-hackers |
Hello,
Thank you for the reviewing.
>> If it's not too much trouble perhaps you could write a few more test
>> so
>> we would have 100% test coverage for rbtree, could modify it safely
>> and
>> be sure that it actually works when someone will need the rest of its
>> functionality?
Done. Now all of the functions in rbtree.c are covered.
> Also I would recommend to add your patch to the nearest commitfest [1].
> Otherwise there is a good chance that everyone will forget about it
> quite soon.
>
> [1]: https://commitfest.postgresql.org/14/
Done. Here is the link: https://commitfest.postgresql.org/14/1225/
Thank you for attention!
--
------
Victor Drobny
Postgres Professional: http://www.postgrespro.com
The Russian Postgres Company
From: | Victor Drobny <v(dot)drobny(at)postgrespro(dot)ru> |
---|---|
To: | Aleksander Alekseev <a(dot)alekseev(at)postgrespro(dot)ru> |
Cc: | Pgsql Hackers <pgsql-hackers(at)postgresql(dot)org>, pgsql-hackers-owner(at)postgresql(dot)org |
Subject: | Re: Red-Black tree traversal tests |
Date: | 2017-08-02 12:15:32 |
Message-ID: | [email protected] |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Lists: | pgsql-hackers |
I forgot to attach the patch. Sorry.
Here it is.
--
------
Victor Drobny
Postgres Professional: http://www.postgrespro.com
The Russian Postgres Company
Attachment | Content-Type | Size |
---|---|---|
rbtree_test.patch | text/x-diff | 20.3 KB |
From: | Aleksander Alekseev <a(dot)alekseev(at)postgrespro(dot)ru> |
---|---|
To: | Victor Drobny <v(dot)drobny(at)postgrespro(dot)ru> |
Cc: | Pgsql Hackers <pgsql-hackers(at)postgresql(dot)org>, pgsql-hackers-owner(at)postgresql(dot)org |
Subject: | Re: Red-Black tree traversal tests |
Date: | 2017-08-03 08:42:22 |
Message-ID: | [email protected] |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Lists: | pgsql-hackers |
Hi Victor,
> I forgot to attach the patch. Sorry.
> Here it is.
I would say that this patch is in a pretty good shape now. And I see a
99% code coverage of rbtree.c. Let's see what committers think.
--
Best regards,
Aleksander Alekseev
From: | Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> |
---|---|
To: | Aleksander Alekseev <a(dot)alekseev(at)postgrespro(dot)ru> |
Cc: | Victor Drobny <v(dot)drobny(at)postgrespro(dot)ru>, Pgsql Hackers <pgsql-hackers(at)postgresql(dot)org> |
Subject: | Re: Red-Black tree traversal tests |
Date: | 2017-09-06 22:38:11 |
Message-ID: | [email protected] |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Lists: | pgsql-hackers |
[ btw, please don't cc pgsql-hackers-owner, the list moderators don't
need the noise ]
Aleksander Alekseev <a(dot)alekseev(at)postgrespro(dot)ru> writes:
> I would say that this patch is in a pretty good shape now. And I see a
> 99% code coverage of rbtree.c. Let's see what committers think.
I took a quick look through the patch --- haven't tried to compile it
or anything like that --- and have a few comments:
* There's some typos, eg extention should be extension, triversal
should be traversal. Maybe try a spell checker?
* The diff complains about lack of file-ending newlines in several
places.
* There's something weird at the start of test.c:
@@ -0,0 +1,577 @@
+/*--------------------------------------------------------------------------
Maybe your compiler thinks that's a BOM? It's hard to see how it
compiles otherwise.
* I think it might be simpler to have the module expose just one SQL
function that invokes all these individual tests internally. Less
boilerplate text that way, and less to change if you add more tests
later. Also, you might consider passing in TEST_SIZE as an argument
of the SQL function instead of having it be hard-wired.
* We don't do C++-style (//) comments around here. Please use C
style. (You might consider running the code through pgindent,
which will convert those comments automatically.)
* It's also generally not per project style to use malloc/calloc/free
directly in backend code; and it's certainly not cool to use malloc or
calloc and then not check for a null result. Use palloc instead. Given
the short runtime of this test, you likely needn't be too worried about
pfree'ing stuff.
* _PG_init() declaration seems to be a leftover? <stdio.h> doesn't
belong here either, as postgres.h will bring that in for you.
* I know next to zip about red-black trees, but it disturbs me that
the traversal tests use trees whose values were inserted in strictly
increasing order. Seems like that's not proving as much as it could.
I wonder how hard it would be to insert those integers in random order.
* I'm not too pleased that the rb_find calls mostly just assume that
the find won't return NULL. You should be testing for that and reporting
the problem, not just dying on a null pointer crash if it happens.
* Possibly the tests should exercise rb_delete on keys *not* present.
And how about insertion of already-existing keys? Although that's
a bit outside the scope of testing traversal, so if you want to leave
it for some future expansion, that'd be OK.
I'll set this back to Waiting on Author. I do encourage you to finish
it up.
regards, tom lane
From: | Victor Drobny <v(dot)drobny(at)postgrespro(dot)ru> |
---|---|
To: | Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> |
Cc: | Aleksander Alekseev <a(dot)alekseev(at)postgrespro(dot)ru>, Pgsql Hackers <pgsql-hackers(at)postgresql(dot)org> |
Subject: | Re: Red-Black tree traversal tests |
Date: | 2017-09-08 09:03:37 |
Message-ID: | [email protected] |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Lists: | pgsql-hackers |
Dear Tom,
Thank you very much for your review. In the attachment you can find v2
of the patch.
On 2017-09-07 01:38, Tom Lane wrote:
> [ btw, please don't cc pgsql-hackers-owner, the list moderators don't
> need the noise ]
>
> Aleksander Alekseev <a(dot)alekseev(at)postgrespro(dot)ru> writes:
>> I would say that this patch is in a pretty good shape now. And I see a
>> 99% code coverage of rbtree.c. Let's see what committers think.
>
> I took a quick look through the patch --- haven't tried to compile it
> or anything like that --- and have a few comments:
>
> * There's some typos, eg extention should be extension, triversal
> should be traversal. Maybe try a spell checker?
Done. I fixed all spelling mistakes that i found.
>
> * The diff complains about lack of file-ending newlines in several
> places
>
> * There's something weird at the start of test.c:
>
> @@ -0,0 +1,577 @@
> +/*--------------------------------------------------------------------------
>
> Maybe your compiler thinks that's a BOM? It's hard to see how it
> compiles otherwise.
Now it is in UTF-8 without BOM. It seems that there is no such data in
the beginning
of the test.c
> * I think it might be simpler to have the module expose just one SQL
> function that invokes all these individual tests internally. Less
> boilerplate text that way, and less to change if you add more tests
> later. Also, you might consider passing in TEST_SIZE as an argument
> of the SQL function instead of having it be hard-wired.
You are right. Done.
>
> * We don't do C++-style (//) comments around here. Please use C
> style. (You might consider running the code through pgindent,
> which will convert those comments automatically.)
Fixed.
>
> * It's also generally not per project style to use malloc/calloc/free
> directly in backend code; and it's certainly not cool to use malloc or
> calloc and then not check for a null result. Use palloc instead.
> Given
> the short runtime of this test, you likely needn't be too worried about
> pfree'ing stuff.
>
> * _PG_init() declaration seems to be a leftover? <stdio.h> doesn't
> belong here either, as postgres.h will bring that in for you.
>
> * I know next to zip about red-black trees, but it disturbs me that
> the traversal tests use trees whose values were inserted in strictly
> increasing order. Seems like that's not proving as much as it could.
> I wonder how hard it would be to insert those integers in random order.
>
> * I'm not too pleased that the rb_find calls mostly just assume that
> the find won't return NULL. You should be testing for that and
> reporting
> the problem, not just dying on a null pointer crash if it happens.
Done.
>
> * Possibly the tests should exercise rb_delete on keys *not* present.
> And how about insertion of already-existing keys? Although that's
> a bit outside the scope of testing traversal, so if you want to leave
> it for some future expansion, that'd be OK.
Deletion requires to get pointer to the tree node. Otherwise it could
break
the tree. It is mentioned in the description of the rb_delete function.
" * "node" must have previously been found via rb_find or rb_leftmost."
Insertion of the same elements is managed by the specific implementation
of the tree. One of the input arguments of the rb_create function is
combiner function that will be called in case of repeated insertion.
However, during looking through this i found that nobody checks that
combiner function(as well as comparator, freefunc and allocfunc) is
not NULL. So if it was not specified, postgres will fall. I think that
it is better to add this checks.
>
> I'll set this back to Waiting on Author. I do encourage you to finish
> it up.
>
> regards, tom lane
--
Victor Drobny
Postgres Professional: http://www.postgrespro.com
The Russian Postgres Company
Attachment | Content-Type | Size |
---|---|---|
rbtree_test_2.patch | text/x-diff | 20.3 KB |
From: | Thomas Munro <thomas(dot)munro(at)enterprisedb(dot)com> |
---|---|
To: | Victor Drobny <v(dot)drobny(at)postgrespro(dot)ru> |
Cc: | Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>, Aleksander Alekseev <a(dot)alekseev(at)postgrespro(dot)ru>, Pgsql Hackers <pgsql-hackers(at)postgresql(dot)org> |
Subject: | Re: Red-Black tree traversal tests |
Date: | 2017-09-08 12:23:35 |
Message-ID: | CAEepm=0BJGpdYN82dze-iGHf4FFWrK9M5kD0uin0Z2kXdw=_UA@mail.gmail.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Lists: | pgsql-hackers |
On Fri, Sep 8, 2017 at 9:03 PM, Victor Drobny <v(dot)drobny(at)postgrespro(dot)ru> wrote:
> Thank you very much for your review. In the attachment you can find v2 of
> the patch.
FYI this version crashes for me:
test test_rbtree ... FAILED (test process exited with exit code 2)
It's trying to call rb->combiner which is null.
(lldb) bt
* thread #1: tid = 0x0000, 0x0000000000000000, stop reason = signal SIGSTOP
frame #0: 0x0000000000000000
* frame #1: 0x000000010c6fd9e0
postgres`rb_insert(rb=0x00007fe7e2029850, data=0x00007fff5380aa10,
isNew="") + 128 at rbtree.c:419
frame #2: 0x000000010cffbfb9
test_rbtree.so`testdelete(size=100000, delsize=10000) + 425 at
test.c:558
frame #3: 0x000000010cffb298
test_rbtree.so`testrbtree(fcinfo=0x00007fe7e200d9a8) + 104 at
test.c:630
frame #4: 0x000000010c6a03be
postgres`ExecInterpExpr(state=0x00007fe7e200d8c0,
econtext=0x00007fe7e200d570, isnull="") + 2702 at execExprInterp.c:672
frame #5: 0x000000010c6e005b
postgres`ExecEvalExprSwitchContext(state=0x00007fe7e200d8c0,
econtext=0x00007fe7e200d570, isNull="") + 59 at executor.h:309
frame #6: 0x000000010c6dffee
postgres`ExecProject(projInfo=0x00007fe7e200d8b8) + 78 at
executor.h:343
frame #7: 0x000000010c6dfd5c
postgres`ExecResult(pstate=0x00007fe7e200d458) + 332 at
nodeResult.c:136
frame #8: 0x000000010c6b2912
postgres`ExecProcNodeFirst(node=0x00007fe7e200d458) + 82 at
execProcnode.c:430
frame #9: 0x000000010c6af352
postgres`ExecProcNode(node=0x00007fe7e200d458) + 50 at executor.h:251
frame #10: 0x000000010c6ab0f6
postgres`ExecutePlan(estate=0x00007fe7e200d240,
planstate=0x00007fe7e200d458, use_parallel_mode='\0',
operation=CMD_SELECT, sendTuples='\x01', numberTuples=0,
direction=ForwardScanDirection, dest=0x00007fe7e200aa20,
execute_once='\x01') + 182 at execMain.c:1720
frame #11: 0x000000010c6aafcb
postgres`standard_ExecutorRun(queryDesc=0x00007fe7e2004040,
direction=ForwardScanDirection, count=0, execute_once='\x01') + 571 at
execMain.c:363
frame #12: 0x000000010c6aad87
postgres`ExecutorRun(queryDesc=0x00007fe7e2004040,
direction=ForwardScanDirection, count=0, execute_once='\x01') + 87 at
execMain.c:306
frame #13: 0x000000010c8b5bf2
postgres`PortalRunSelect(portal=0x00007fe7e2000040, forward='\x01',
count=0, dest=0x00007fe7e200aa20) + 306 at pquery.c:932
frame #14: 0x000000010c8b55ba
postgres`PortalRun(portal=0x00007fe7e2000040,
count=9223372036854775807, isTopLevel='\x01', run_once='\x01',
dest=0x00007fe7e200aa20, altdest=0x00007fe7e200aa20, completionTag="")
+ 762 at pquery.c:773
frame #15: 0x000000010c8b0f24
postgres`exec_simple_query(query_string="SELECT testrbtree(100000);")
+ 1316 at postgres.c:1109
frame #16: 0x000000010c8b0127 postgres`PostgresMain(argc=1,
argv=0x00007fe7e180bd10, dbname="contrib_regression",
username="munro") + 2375 at postgres.c:4103
frame #17: 0x000000010c7f712e
postgres`BackendRun(port=0x00007fe7e0d00db0) + 654 at
postmaster.c:4357
frame #18: 0x000000010c7f64b3
postgres`BackendStartup(port=0x00007fe7e0d00db0) + 483 at
postmaster.c:4029
frame #19: 0x000000010c7f54a5 postgres`ServerLoop + 597 at postmaster.c:1753
frame #20: 0x000000010c7f2c91 postgres`PostmasterMain(argc=8,
argv=0x00007fe7e0c03860) + 5553 at postmaster.c:1361
frame #21: 0x000000010c716799 postgres`main(argc=8,
argv=0x00007fe7e0c03860) + 761 at main.c:228
frame #22: 0x00007fff8333a5ad libdyld.dylib`start + 1
(lldb) f 1
frame #1: 0x000000010c6fd9e0 postgres`rb_insert(rb=0x00007fe7e2029850,
data=0x00007fff5380aa10, isNew="") + 128 at rbtree.c:419
416 /*
417 * Found node with given key. Apply combiner.
418 */
-> 419 rb->combiner(current, data, rb->arg);
420 *isNew = false;
421 return current;
422 }
(lldb) print *rb
(RBTree) $2 = {
root = 0x00007fe7e4419b60
node_size = 40
comparator = 0x000000010cffc310 (test_rbtree.so`cmp at int_rbtree.h:28)
combiner = 0x0000000000000000
allocfunc = 0x000000010cffc340 (test_rbtree.so`alloc at int_rbtree.h:37)
freefunc = 0x000000010cffc370 (test_rbtree.so`fr at int_rbtree.h:45)
arg = 0x0000000000000000
}
--
Thomas Munro
http://www.enterprisedb.com
From: | Victor Drobny <v(dot)drobny(at)postgrespro(dot)ru> |
---|---|
To: | Thomas Munro <thomas(dot)munro(at)enterprisedb(dot)com> |
Cc: | Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>, Aleksander Alekseev <a(dot)alekseev(at)postgrespro(dot)ru>, Pgsql Hackers <pgsql-hackers(at)postgresql(dot)org> |
Subject: | Re: Red-Black tree traversal tests |
Date: | 2017-09-08 15:44:00 |
Message-ID: | [email protected] |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Lists: | pgsql-hackers |
On 2017-09-08 15:23, Thomas Munro wrote:
> On Fri, Sep 8, 2017 at 9:03 PM, Victor Drobny <v(dot)drobny(at)postgrespro(dot)ru>
> wrote:
>> Thank you very much for your review. In the attachment you can find v2
>> of
>> the patch.
>
> FYI this version crashes for me:
>
> test test_rbtree ... FAILED (test process exited with exit
> code 2)
>
> It's trying to call rb->combiner which is null.
>
Thank you for pointing on it. Here is a fixed version.
--
Victor Drobny
Postgres Professional: http://www.postgrespro.com
The Russian Postgres Company
Attachment | Content-Type | Size |
---|---|---|
rbtree_test_3.patch | text/x-diff | 20.1 KB |
From: | Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> |
---|---|
To: | Victor Drobny <v(dot)drobny(at)postgrespro(dot)ru> |
Cc: | Thomas Munro <thomas(dot)munro(at)enterprisedb(dot)com>, Aleksander Alekseev <a(dot)alekseev(at)postgrespro(dot)ru>, Pgsql Hackers <pgsql-hackers(at)postgresql(dot)org> |
Subject: | Re: Red-Black tree traversal tests |
Date: | 2017-09-10 00:07:00 |
Message-ID: | [email protected] |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Lists: | pgsql-hackers |
Victor Drobny <v(dot)drobny(at)postgrespro(dot)ru> writes:
> On 2017-09-08 15:23, Thomas Munro wrote:
>> It's trying to call rb->combiner which is null.
> Thank you for pointing on it. Here is a fixed version.
Actually, I think we *do* want the tests to call the combiner
occasionally ...
I whacked this around quite a bit and had gotten it to a state
that I thought was committable, when it occurred to me to wonder
why exactly we're going to this much effort to test the preorder
and postorder traversal logic. I'm inclined to think we should
rip that out, instead, because I can think of no reason that
anyone would ever want to use it in Postgres.
I'll make that argument in a separate thread, so it gets a little
more visibility in the pgsql-hackers firehose.
In the meantime, here's my version. Notable changes:
* Got rid of separate .h file; seemed pointless, especially
since the combiner function needs to know what the test
expectations are.
* Corrected the random-permutation algorithm.
* Made the preorder/postorder check logic more paranoid
(though I now feel that was a waste of effort).
* Improved English grammar in a lot of comments.
* Added some more test cases; code coverage report shows
that this exercises every non-error-case line in rbtree.c.
* Added an rbtree "rb_root()" function to avoid the unsafe
casting the previous version did to get the root pointer.
* Removed the assumption that the nil element is unique;
now it just knows that a leaf element points to itself.
We could dispense with rb_root(), as well as the test code's knowledge
about RBNIL representation, if we dropped the preorder/postorder cases
... which is another good reason to do so.
regards, tom lane
Attachment | Content-Type | Size |
---|---|---|
rbtree_test_4.patch | text/x-diff | 25.4 KB |
From: | Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> |
---|---|
To: | Victor Drobny <v(dot)drobny(at)postgrespro(dot)ru> |
Cc: | Thomas Munro <thomas(dot)munro(at)enterprisedb(dot)com>, Aleksander Alekseev <a(dot)alekseev(at)postgrespro(dot)ru>, Pgsql Hackers <pgsql-hackers(at)postgresql(dot)org> |
Subject: | Re: Red-Black tree traversal tests |
Date: | 2017-09-10 17:32:22 |
Message-ID: | [email protected] |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Lists: | pgsql-hackers |
I wrote:
> In the meantime, here's my version. Notable changes:
I went ahead and pushed this, with the removal of the preorder/postorder
code, so we can see if the buildfarm finds out anything interesting.
Feel free to continue to submit improvements though.
One thing that occurred to me is that as-is, this is entirely black-box
testing. It doesn't try to check that the tree actually satisfies the
RB invariants, which is something that is interesting for performance
reasons. (That is, the code could pass these tests even though it
produces an unbalanced tree with horrible performance.) Is it worth
adding logic for that? Not sure. It's not like we are actively
changing the RB code or have reason to think it is buggy.
regards, tom lane