You are viewing a plain text version of this content. The canonical link for it is here.
Posted to reviews@kudu.apache.org by "Adar Dembo (Code Review)" <ge...@cloudera.org> on 2019/01/09 09:42:56 UTC

[kudu-CR] generic iterators: basic MergeIterator dominance

Hello Mike Percy, Grant Henke, Todd Lipcon,

I'd like you to do a code review. Please visit

    http://gerrit.cloudera.org:8080/12197

to review the following change.


Change subject: generic_iterators: basic MergeIterator dominance
......................................................................

generic_iterators: basic MergeIterator dominance

This patch adds a dominance algorithm to the MergeIterator. The idea is:
rather than considering every sub-iterator for merging, we can omit a
sub-iterator if its current block's last primary key is lexicographically
greater than another sub-iterator's current block's first primary key. In
this state the omitted sub-iterator is said to be "fully dominated" and the
two sub-iterators are said to have a "dominance relation".

We're already using a similar algorithm in merge compaction (see
MergeCompactionInput in compaction.cc). I toyed with the idea of reusing the
code but found it to be too unwieldy to be workable.

Additionally, because dominance relations come and go as blocks are pulled,
this patch also makes all MergeIterState lists intrusive.

To test, I ran TestMerge and TestMergeOverlap twice with --num-lists=50:
once with dominance and once without. The table below captures the
MergeIterator histogram for all four runs.

             Basic-overlap | basic-nonoverlap | dom-overlap | dom-nonoverlap
             --------------+------------------+-------------+---------------
total count: 43699         | 43664            | 43840       | 43631
total sum:   2155405       | 1113852          | 2059279     | 417242
min:         1             | 1                | 1           | 1
mean:        49.3239       | 25.5096          | 46.9726     | 9.56297
p75:         50            | 38               | 48          | 15
p95:         50            | 48               | 50          | 20
p99:         50            | 50               | 50          | 21
p99.9:       50            | 50               | 50          | 21
p99.99:      50            | 50               | 50          | 21
max:         50            | 50               | 50          | 21

The results show a mild improvement when the input is fully overlapping and
a more significant one (almost 3x) when non-overlapping. Real tablets are
likely to fall in between the two ends of the spectrum, edging closer to
non-overlapping the more they are compacted.

More optimizations are on the way:
- Better memory consumption by establishing dominance using rowset bounds.
- Faster merge by copying block-by-block when there's only one non-dominated
  sub-iterator.

Change-Id: If59d831240af15bfa7ef5709ec3d105d13b28322
---
M src/kudu/common/generic_iterators.cc
M src/kudu/common/generic_iterators.h
2 files changed, 214 insertions(+), 67 deletions(-)



  git pull ssh://gerrit.cloudera.org:29418/kudu refs/changes/97/12197/1
-- 
To view, visit http://gerrit.cloudera.org:8080/12197
To unsubscribe, visit http://gerrit.cloudera.org:8080/settings

Gerrit-Project: kudu
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: If59d831240af15bfa7ef5709ec3d105d13b28322
Gerrit-Change-Number: 12197
Gerrit-PatchSet: 1
Gerrit-Owner: Adar Dembo <ad...@cloudera.com>
Gerrit-Reviewer: Grant Henke <gr...@apache.org>
Gerrit-Reviewer: Mike Percy <mp...@apache.org>
Gerrit-Reviewer: Todd Lipcon <to...@apache.org>

[kudu-CR] generic iterators: basic MergeIterator dominance

Posted by "Todd Lipcon (Code Review)" <ge...@cloudera.org>.
Todd Lipcon has posted comments on this change. ( http://gerrit.cloudera.org:8080/12197 )

Change subject: generic_iterators: basic MergeIterator dominance
......................................................................


Patch Set 5:

(4 comments)

http://gerrit.cloudera.org:8080/#/c/12197/5//COMMIT_MSG
Commit Message:

http://gerrit.cloudera.org:8080/#/c/12197/5//COMMIT_MSG@11
PS5, Line 11: sub-iterator if its current block's last primary key is lexicographically
            : greater than another sub-iterator's current block's first primary key
is this phrased backwards? ie:

If we have sub-iterators A and B, where the last key of A is less than the first key of B, then we can say that A dominates B.


http://gerrit.cloudera.org:8080/#/c/12197/5/src/kudu/common/generic_iterators.cc
File src/kudu/common/generic_iterators.cc:

http://gerrit.cloudera.org:8080/#/c/12197/5/src/kudu/common/generic_iterators.cc@536
PS5, Line 536:     for (const auto& dominated_s : s.dominated()) {
is it worth adding:

  if (available >= dst->row_capacity()) break;

here, given we're going to 'min()' it anyway? that avoids iterating over all sub-iters for every batch. I think the common case is that we could early-out very quickly.


http://gerrit.cloudera.org:8080/#/c/12197/5/src/kudu/common/generic_iterators.cc@593
PS5, Line 593:       // main list.
if the dominated iterators were stored as a min-heap by their min_key, this could be an O(1) check instead of O(n), right?


http://gerrit.cloudera.org:8080/#/c/12197/5/src/kudu/common/generic_iterators.cc@606
PS5, Line 606:       for (auto& s : states_) {
similarly here if we have a heap of states_ we could O(1) find the state_ with the smallest max_key and check if that now dominates the newly exposed min_key?



-- 
To view, visit http://gerrit.cloudera.org:8080/12197
To unsubscribe, visit http://gerrit.cloudera.org:8080/settings

Gerrit-Project: kudu
Gerrit-Branch: master
Gerrit-MessageType: comment
Gerrit-Change-Id: If59d831240af15bfa7ef5709ec3d105d13b28322
Gerrit-Change-Number: 12197
Gerrit-PatchSet: 5
Gerrit-Owner: Adar Dembo <ad...@cloudera.com>
Gerrit-Reviewer: Adar Dembo <ad...@cloudera.com>
Gerrit-Reviewer: Grant Henke <gr...@apache.org>
Gerrit-Reviewer: Kudu Jenkins (120)
Gerrit-Reviewer: Mike Percy <mp...@apache.org>
Gerrit-Reviewer: Todd Lipcon <to...@apache.org>
Gerrit-Comment-Date: Sat, 12 Jan 2019 00:21:16 +0000
Gerrit-HasComments: Yes

[kudu-CR] generic iterators: basic MergeIterator dominance

Posted by "Todd Lipcon (Code Review)" <ge...@cloudera.org>.
Todd Lipcon has posted comments on this change. ( http://gerrit.cloudera.org:8080/12197 )

Change subject: generic_iterators: basic MergeIterator dominance
......................................................................


Patch Set 4:

(1 comment)

http://gerrit.cloudera.org:8080/#/c/12197/4//COMMIT_MSG
Commit Message:

http://gerrit.cloudera.org:8080/#/c/12197/4//COMMIT_MSG@25
PS4, Line 25: MergeIterator histogram for all four runs.
per some comment earlier in the patch series, I'd be more interested in knowing overall CPU reduction of this optimization. Intuitively we're now doing some work to check for dominance relations which might cost us something, but we expect to see a reduction in total CPU because we skip all the unnecessary comparisons, right?



-- 
To view, visit http://gerrit.cloudera.org:8080/12197
To unsubscribe, visit http://gerrit.cloudera.org:8080/settings

Gerrit-Project: kudu
Gerrit-Branch: master
Gerrit-MessageType: comment
Gerrit-Change-Id: If59d831240af15bfa7ef5709ec3d105d13b28322
Gerrit-Change-Number: 12197
Gerrit-PatchSet: 4
Gerrit-Owner: Adar Dembo <ad...@cloudera.com>
Gerrit-Reviewer: Grant Henke <gr...@apache.org>
Gerrit-Reviewer: Kudu Jenkins (120)
Gerrit-Reviewer: Mike Percy <mp...@apache.org>
Gerrit-Reviewer: Todd Lipcon <to...@apache.org>
Gerrit-Comment-Date: Wed, 09 Jan 2019 23:32:22 +0000
Gerrit-HasComments: Yes

[kudu-CR] generic iterators: basic MergeIterator dominance

Posted by "Adar Dembo (Code Review)" <ge...@cloudera.org>.
Adar Dembo has posted comments on this change. ( http://gerrit.cloudera.org:8080/12197 )

Change subject: generic_iterators: basic MergeIterator dominance
......................................................................


Patch Set 7:

(1 comment)

http://gerrit.cloudera.org:8080/#/c/12197/7/src/kudu/common/generic_iterators.cc
File src/kudu/common/generic_iterators.cc:

http://gerrit.cloudera.org:8080/#/c/12197/7/src/kudu/common/generic_iterators.cc@589
PS7, Line 589:       // Move all sub-iterators dominated by 'smallest' back into the main list
             :       // before destroying 'smallest'.
I think we need to recheck these sub-iterators for dominance instead of moving them back into states_.

The algorithm that establishes dominance relations when the MergeIterator is initialized is greedy, and thus which relations are established is a function of the order of iterators passed to the constructor. Thus, it's possible to start off with "sub-optimal" relations (i.e. relations that will be broken earlier in the merge).

Consider this example:
- Iter A with block [5, 10]
- Iter B with block [16, 20]
- Iter C with block [11, 15]

If initialization yielded dominance relations A>B and A>C, when we fully exhaust A we should establish C>B. The current code would just throw both back into states_.

Mike/Todd, what do you guys think?



-- 
To view, visit http://gerrit.cloudera.org:8080/12197
To unsubscribe, visit http://gerrit.cloudera.org:8080/settings

Gerrit-Project: kudu
Gerrit-Branch: master
Gerrit-MessageType: comment
Gerrit-Change-Id: If59d831240af15bfa7ef5709ec3d105d13b28322
Gerrit-Change-Number: 12197
Gerrit-PatchSet: 7
Gerrit-Owner: Adar Dembo <ad...@cloudera.com>
Gerrit-Reviewer: Adar Dembo <ad...@cloudera.com>
Gerrit-Reviewer: Grant Henke <gr...@apache.org>
Gerrit-Reviewer: Kudu Jenkins (120)
Gerrit-Reviewer: Mike Percy <mp...@apache.org>
Gerrit-Reviewer: Todd Lipcon <to...@apache.org>
Gerrit-Comment-Date: Thu, 24 Jan 2019 02:13:39 +0000
Gerrit-HasComments: Yes

[kudu-CR] generic iterators: basic MergeIterator dominance

Posted by "Adar Dembo (Code Review)" <ge...@cloudera.org>.
Hello Mike Percy, Kudu Jenkins, Grant Henke, Todd Lipcon, 

I'd like you to reexamine a change. Please visit

    http://gerrit.cloudera.org:8080/12197

to look at the new patch set (#6).

Change subject: generic_iterators: basic MergeIterator dominance
......................................................................

generic_iterators: basic MergeIterator dominance

This patch adds a dominance algorithm to the MergeIterator. The idea is:
rather than considering every sub-iterator for merging, we can temporarily
omit sub-iterator A if its current block's first primary key is
lexicographically greater than another sub-iterator B's current block's last
primary key. When this holds, we will always choose B's rows over A's, so
there's no point in even considering A in the merge until B switches to a
new current block. More formally, A is said to be "fully dominated" by B,
and A and B are said to have a "dominance relation".

We're already using a similar algorithm in merge compaction (see
MergeCompactionInput in compaction.cc). I toyed with the idea of reusing the
code but found it to be too unwieldy to be workable.

Additionally, because dominance relations come and go as blocks are pulled,
this patch also makes all MergeIterState lists intrusive.

I ran both TestMerge and TestMergeOverlap with --num-lists=100, once with
dominance and once without. The table below shows the average number of
comparisons and running time (across 10 iterations) for all four cases.

        Basic-overlap | basic-nonoverlap | dom-overlap   | dom-nonoverlap
        --------------+------------------+---------------+---------------
avg comps: 86,289,036 | 43,316,333       | 81,976,599    | 18,364,238
avg rt: 1.31s +- 0.6% | 0.57s +- 1.2%    | 1.20s +- 0.7% | 0.28s +- 9.4%

The results show a mild improvement in running time when the input is fully
overlapping and a more significant one (about 2x) when non-overlapping. Real
tablets are likely to fall in between the two ends of the spectrum, edging
closer to non-overlapping the more they are compacted. Note: the higher
variances in the non-overlapped runs are due to more significant differences
between the merge input.

More optimizations are on the way:
- Better memory consumption by establishing dominance using rowset bounds.
- Faster merge by copying block-by-block when there's only one non-dominated
  sub-iterator.
- Use of min-heaps instead of lists to speed up dominance checking.

Change-Id: If59d831240af15bfa7ef5709ec3d105d13b28322
---
M src/kudu/common/generic_iterators-test.cc
M src/kudu/common/generic_iterators.cc
2 files changed, 260 insertions(+), 58 deletions(-)


  git pull ssh://gerrit.cloudera.org:29418/kudu refs/changes/97/12197/6
-- 
To view, visit http://gerrit.cloudera.org:8080/12197
To unsubscribe, visit http://gerrit.cloudera.org:8080/settings

Gerrit-Project: kudu
Gerrit-Branch: master
Gerrit-MessageType: newpatchset
Gerrit-Change-Id: If59d831240af15bfa7ef5709ec3d105d13b28322
Gerrit-Change-Number: 12197
Gerrit-PatchSet: 6
Gerrit-Owner: Adar Dembo <ad...@cloudera.com>
Gerrit-Reviewer: Adar Dembo <ad...@cloudera.com>
Gerrit-Reviewer: Grant Henke <gr...@apache.org>
Gerrit-Reviewer: Kudu Jenkins (120)
Gerrit-Reviewer: Mike Percy <mp...@apache.org>
Gerrit-Reviewer: Todd Lipcon <to...@apache.org>

[kudu-CR] generic iterators: basic MergeIterator dominance

Posted by "Adar Dembo (Code Review)" <ge...@cloudera.org>.
Adar Dembo has abandoned this change. ( http://gerrit.cloudera.org:8080/12197 )

Change subject: generic_iterators: basic MergeIterator dominance
......................................................................


Abandoned

This has been superceded by https://gerrit.cloudera.org/c/12947/
-- 
To view, visit http://gerrit.cloudera.org:8080/12197
To unsubscribe, visit http://gerrit.cloudera.org:8080/settings

Gerrit-Project: kudu
Gerrit-Branch: master
Gerrit-MessageType: abandon
Gerrit-Change-Id: If59d831240af15bfa7ef5709ec3d105d13b28322
Gerrit-Change-Number: 12197
Gerrit-PatchSet: 8
Gerrit-Owner: Adar Dembo <ad...@cloudera.com>
Gerrit-Reviewer: Adar Dembo <ad...@cloudera.com>
Gerrit-Reviewer: Grant Henke <gr...@apache.org>
Gerrit-Reviewer: Kudu Jenkins (120)
Gerrit-Reviewer: Mike Percy <mp...@apache.org>
Gerrit-Reviewer: Todd Lipcon <to...@apache.org>

[kudu-CR] generic iterators: basic MergeIterator dominance

Posted by "Mike Percy (Code Review)" <ge...@cloudera.org>.
Mike Percy has posted comments on this change. ( http://gerrit.cloudera.org:8080/12197 )

Change subject: generic_iterators: basic MergeIterator dominance
......................................................................


Patch Set 7: Code-Review+2

(6 comments)

http://gerrit.cloudera.org:8080/#/c/12197/7/src/kudu/common/generic_iterators.cc
File src/kudu/common/generic_iterators.cc:

http://gerrit.cloudera.org:8080/#/c/12197/7/src/kudu/common/generic_iterators.cc@102
PS7, Line 102: <>
I think you can remove the need for dispose, etc in the implementation by specifying

  : public list_base_hook<void_pointer<std::unique_ptr<void>>>

Have you tried something like that? Per https://www.boost.org/doc/libs/1_69_0/doc/html/intrusive/using_smart_pointers.html

I am not 100% sure about this, though, and maybe it's less relevant if we are using disposal lambdas to move elements between lists.


http://gerrit.cloudera.org:8080/#/c/12197/7/src/kudu/common/generic_iterators.cc@104
PS7, Line 104: NOLINT(*)
Just curious: why is NOLINT necessary? How about a "using" alias declaration instead, if that prevents the lint warning?


http://gerrit.cloudera.org:8080/#/c/12197/7/src/kudu/common/generic_iterators.cc@274
PS7, Line 274: underflowing
nit: overflow in the negative direction is still overflow as opposed to insufficient precision


http://gerrit.cloudera.org:8080/#/c/12197/7/src/kudu/common/generic_iterators.cc@333
PS7, Line 333: domination
makes me think of https://www.youtube.com/watch?v=lYPFrXvc2rE&t=2m34s ??


http://gerrit.cloudera.org:8080/#/c/12197/7/src/kudu/common/generic_iterators.cc@459
PS7, Line 459:    restart_inner_loop:
nit: indentation here appears to be 3 spaces and I assume you meant it to be 0 or 6 spaces?


http://gerrit.cloudera.org:8080/#/c/12197/7/src/kudu/common/generic_iterators.cc@608
PS7, Line 608: bounds are
lower bound is?



-- 
To view, visit http://gerrit.cloudera.org:8080/12197
To unsubscribe, visit http://gerrit.cloudera.org:8080/settings

Gerrit-Project: kudu
Gerrit-Branch: master
Gerrit-MessageType: comment
Gerrit-Change-Id: If59d831240af15bfa7ef5709ec3d105d13b28322
Gerrit-Change-Number: 12197
Gerrit-PatchSet: 7
Gerrit-Owner: Adar Dembo <ad...@cloudera.com>
Gerrit-Reviewer: Adar Dembo <ad...@cloudera.com>
Gerrit-Reviewer: Grant Henke <gr...@apache.org>
Gerrit-Reviewer: Kudu Jenkins (120)
Gerrit-Reviewer: Mike Percy <mp...@apache.org>
Gerrit-Reviewer: Todd Lipcon <to...@apache.org>
Gerrit-Comment-Date: Thu, 24 Jan 2019 08:56:52 +0000
Gerrit-HasComments: Yes

[kudu-CR] generic iterators: basic MergeIterator dominance

Posted by "Adar Dembo (Code Review)" <ge...@cloudera.org>.
Adar Dembo has posted comments on this change. ( http://gerrit.cloudera.org:8080/12197 )

Change subject: generic_iterators: basic MergeIterator dominance
......................................................................


Patch Set 8: Code-Review-2

I'm looking into whether it's possible to express this algorithm in a cleaner, more understandable way. For example, one of the challenges of 'dominance' has been knowing exactly when to recheck for dominance relations, and exactly what the minimal set of sub-iterators to reexamine needs to be.

For now let's not merge this.


-- 
To view, visit http://gerrit.cloudera.org:8080/12197
To unsubscribe, visit http://gerrit.cloudera.org:8080/settings

Gerrit-Project: kudu
Gerrit-Branch: master
Gerrit-MessageType: comment
Gerrit-Change-Id: If59d831240af15bfa7ef5709ec3d105d13b28322
Gerrit-Change-Number: 12197
Gerrit-PatchSet: 8
Gerrit-Owner: Adar Dembo <ad...@cloudera.com>
Gerrit-Reviewer: Adar Dembo <ad...@cloudera.com>
Gerrit-Reviewer: Grant Henke <gr...@apache.org>
Gerrit-Reviewer: Kudu Jenkins (120)
Gerrit-Reviewer: Mike Percy <mp...@apache.org>
Gerrit-Reviewer: Todd Lipcon <to...@apache.org>
Gerrit-Comment-Date: Mon, 28 Jan 2019 19:30:21 +0000
Gerrit-HasComments: No

[kudu-CR] generic iterators: basic MergeIterator dominance

Posted by "Adar Dembo (Code Review)" <ge...@cloudera.org>.
Hello Mike Percy, Kudu Jenkins, Grant Henke, Todd Lipcon, 

I'd like you to reexamine a change. Please visit

    http://gerrit.cloudera.org:8080/12197

to look at the new patch set (#5).

Change subject: generic_iterators: basic MergeIterator dominance
......................................................................

generic_iterators: basic MergeIterator dominance

This patch adds a dominance algorithm to the MergeIterator. The idea is:
rather than considering every sub-iterator for merging, we can omit a
sub-iterator if its current block's last primary key is lexicographically
greater than another sub-iterator's current block's first primary key. In
this state the omitted sub-iterator is said to be "fully dominated" and the
two sub-iterators are said to have a "dominance relation".

We're already using a similar algorithm in merge compaction (see
MergeCompactionInput in compaction.cc). I toyed with the idea of reusing the
code but found it to be too unwieldy to be workable.

Additionally, because dominance relations come and go as blocks are pulled,
this patch also makes all MergeIterState lists intrusive.

I ran both TestMerge and TestMergeOverlap with --num-lists=100, once with
dominance and once without. The table below shows the average number of
comparisons and running time (across 10 iterations) for all four cases.

        Basic-overlap | basic-nonoverlap | dom-overlap   | dom-nonoverlap
        --------------+------------------+---------------+---------------
avg comps: 86,289,036 | 43,316,333       | 81,976,599    | 18,364,238
avg rt: 1.31s +- 0.6% | 0.57s +- 1.2%    | 1.20s +- 0.7% | 0.28s +- 9.4%

The results show a mild improvement in running time when the input is fully
overlapping and a more significant one (about 2x) when non-overlapping. Real
tablets are likely to fall in between the two ends of the spectrum, edging
closer to non-overlapping the more they are compacted. Note: the higher
variances in the non-overlapped runs are due to more significant differences
between the merge input.

More optimizations are on the way:
- Better memory consumption by establishing dominance using rowset bounds.
- Faster merge by copying block-by-block when there's only one non-dominated
  sub-iterator.

Change-Id: If59d831240af15bfa7ef5709ec3d105d13b28322
---
M src/kudu/common/generic_iterators-test.cc
M src/kudu/common/generic_iterators.cc
2 files changed, 258 insertions(+), 58 deletions(-)


  git pull ssh://gerrit.cloudera.org:29418/kudu refs/changes/97/12197/5
-- 
To view, visit http://gerrit.cloudera.org:8080/12197
To unsubscribe, visit http://gerrit.cloudera.org:8080/settings

Gerrit-Project: kudu
Gerrit-Branch: master
Gerrit-MessageType: newpatchset
Gerrit-Change-Id: If59d831240af15bfa7ef5709ec3d105d13b28322
Gerrit-Change-Number: 12197
Gerrit-PatchSet: 5
Gerrit-Owner: Adar Dembo <ad...@cloudera.com>
Gerrit-Reviewer: Grant Henke <gr...@apache.org>
Gerrit-Reviewer: Kudu Jenkins (120)
Gerrit-Reviewer: Mike Percy <mp...@apache.org>
Gerrit-Reviewer: Todd Lipcon <to...@apache.org>

[kudu-CR] generic iterators: basic MergeIterator dominance

Posted by "Adar Dembo (Code Review)" <ge...@cloudera.org>.
Hello Mike Percy, Kudu Jenkins, Grant Henke, Todd Lipcon, 

I'd like you to reexamine a change. Please visit

    http://gerrit.cloudera.org:8080/12197

to look at the new patch set (#3).

Change subject: generic_iterators: basic MergeIterator dominance
......................................................................

generic_iterators: basic MergeIterator dominance

This patch adds a dominance algorithm to the MergeIterator. The idea is:
rather than considering every sub-iterator for merging, we can omit a
sub-iterator if its current block's last primary key is lexicographically
greater than another sub-iterator's current block's first primary key. In
this state the omitted sub-iterator is said to be "fully dominated" and the
two sub-iterators are said to have a "dominance relation".

We're already using a similar algorithm in merge compaction (see
MergeCompactionInput in compaction.cc). I toyed with the idea of reusing the
code but found it to be too unwieldy to be workable.

Additionally, because dominance relations come and go as blocks are pulled,
this patch also makes all MergeIterState lists intrusive.

To test, I ran TestMerge and TestMergeOverlap twice with --num-lists=50:
once with dominance and once without. The table below captures the
MergeIterator histogram for all four runs.

             Basic-overlap | basic-nonoverlap | dom-overlap | dom-nonoverlap
             --------------+------------------+-------------+---------------
total count: 43699         | 43664            | 43840       | 43631
total sum:   2155405       | 1113852          | 2059279     | 417242
min:         1             | 1                | 1           | 1
mean:        49.3239       | 25.5096          | 46.9726     | 9.56297
p75:         50            | 38               | 48          | 15
p95:         50            | 48               | 50          | 20
p99:         50            | 50               | 50          | 21
p99.9:       50            | 50               | 50          | 21
p99.99:      50            | 50               | 50          | 21
max:         50            | 50               | 50          | 21

The results show a mild improvement when the input is fully overlapping and
a more significant one (almost 3x) when non-overlapping. Real tablets are
likely to fall in between the two ends of the spectrum, edging closer to
non-overlapping the more they are compacted.

More optimizations are on the way:
- Better memory consumption by establishing dominance using rowset bounds.
- Faster merge by copying block-by-block when there's only one non-dominated
  sub-iterator.

Change-Id: If59d831240af15bfa7ef5709ec3d105d13b28322
---
M src/kudu/common/generic_iterators-test.cc
M src/kudu/common/generic_iterators.cc
M src/kudu/common/generic_iterators.h
3 files changed, 296 insertions(+), 68 deletions(-)


  git pull ssh://gerrit.cloudera.org:29418/kudu refs/changes/97/12197/3
-- 
To view, visit http://gerrit.cloudera.org:8080/12197
To unsubscribe, visit http://gerrit.cloudera.org:8080/settings

Gerrit-Project: kudu
Gerrit-Branch: master
Gerrit-MessageType: newpatchset
Gerrit-Change-Id: If59d831240af15bfa7ef5709ec3d105d13b28322
Gerrit-Change-Number: 12197
Gerrit-PatchSet: 3
Gerrit-Owner: Adar Dembo <ad...@cloudera.com>
Gerrit-Reviewer: Grant Henke <gr...@apache.org>
Gerrit-Reviewer: Kudu Jenkins (120)
Gerrit-Reviewer: Mike Percy <mp...@apache.org>
Gerrit-Reviewer: Todd Lipcon <to...@apache.org>

[kudu-CR] generic iterators: basic MergeIterator dominance

Posted by "Adar Dembo (Code Review)" <ge...@cloudera.org>.
Adar Dembo has posted comments on this change. ( http://gerrit.cloudera.org:8080/12197 )

Change subject: generic_iterators: basic MergeIterator dominance
......................................................................


Patch Set 4:

(1 comment)

http://gerrit.cloudera.org:8080/#/c/12197/4//COMMIT_MSG
Commit Message:

http://gerrit.cloudera.org:8080/#/c/12197/4//COMMIT_MSG@25
PS4, Line 25: MergeIterator histogram for all four runs.
> per some comment earlier in the patch series, I'd be more interested in kno
I've replaced this with the average number of comparisons performed and microbenchmark running time.

If you want raw perf stat output I can show that too; it's just quite verbose given the four different runs so I didn't want to include it in the commit message.



-- 
To view, visit http://gerrit.cloudera.org:8080/12197
To unsubscribe, visit http://gerrit.cloudera.org:8080/settings

Gerrit-Project: kudu
Gerrit-Branch: master
Gerrit-MessageType: comment
Gerrit-Change-Id: If59d831240af15bfa7ef5709ec3d105d13b28322
Gerrit-Change-Number: 12197
Gerrit-PatchSet: 4
Gerrit-Owner: Adar Dembo <ad...@cloudera.com>
Gerrit-Reviewer: Adar Dembo <ad...@cloudera.com>
Gerrit-Reviewer: Grant Henke <gr...@apache.org>
Gerrit-Reviewer: Kudu Jenkins (120)
Gerrit-Reviewer: Mike Percy <mp...@apache.org>
Gerrit-Reviewer: Todd Lipcon <to...@apache.org>
Gerrit-Comment-Date: Fri, 11 Jan 2019 23:53:54 +0000
Gerrit-HasComments: Yes

[kudu-CR] generic iterators: basic MergeIterator dominance

Posted by "Adar Dembo (Code Review)" <ge...@cloudera.org>.
Hello Mike Percy, Kudu Jenkins, Grant Henke, Todd Lipcon, 

I'd like you to reexamine a change. Please visit

    http://gerrit.cloudera.org:8080/12197

to look at the new patch set (#2).

Change subject: generic_iterators: basic MergeIterator dominance
......................................................................

generic_iterators: basic MergeIterator dominance

This patch adds a dominance algorithm to the MergeIterator. The idea is:
rather than considering every sub-iterator for merging, we can omit a
sub-iterator if its current block's last primary key is lexicographically
greater than another sub-iterator's current block's first primary key. In
this state the omitted sub-iterator is said to be "fully dominated" and the
two sub-iterators are said to have a "dominance relation".

We're already using a similar algorithm in merge compaction (see
MergeCompactionInput in compaction.cc). I toyed with the idea of reusing the
code but found it to be too unwieldy to be workable.

Additionally, because dominance relations come and go as blocks are pulled,
this patch also makes all MergeIterState lists intrusive.

To test, I ran TestMerge and TestMergeOverlap twice with --num-lists=50:
once with dominance and once without. The table below captures the
MergeIterator histogram for all four runs.

             Basic-overlap | basic-nonoverlap | dom-overlap | dom-nonoverlap
             --------------+------------------+-------------+---------------
total count: 43699         | 43664            | 43840       | 43631
total sum:   2155405       | 1113852          | 2059279     | 417242
min:         1             | 1                | 1           | 1
mean:        49.3239       | 25.5096          | 46.9726     | 9.56297
p75:         50            | 38               | 48          | 15
p95:         50            | 48               | 50          | 20
p99:         50            | 50               | 50          | 21
p99.9:       50            | 50               | 50          | 21
p99.99:      50            | 50               | 50          | 21
max:         50            | 50               | 50          | 21

The results show a mild improvement when the input is fully overlapping and
a more significant one (almost 3x) when non-overlapping. Real tablets are
likely to fall in between the two ends of the spectrum, edging closer to
non-overlapping the more they are compacted.

More optimizations are on the way:
- Better memory consumption by establishing dominance using rowset bounds.
- Faster merge by copying block-by-block when there's only one non-dominated
  sub-iterator.

Change-Id: If59d831240af15bfa7ef5709ec3d105d13b28322
---
M src/kudu/common/generic_iterators-test.cc
M src/kudu/common/generic_iterators.cc
M src/kudu/common/generic_iterators.h
3 files changed, 256 insertions(+), 68 deletions(-)


  git pull ssh://gerrit.cloudera.org:29418/kudu refs/changes/97/12197/2
-- 
To view, visit http://gerrit.cloudera.org:8080/12197
To unsubscribe, visit http://gerrit.cloudera.org:8080/settings

Gerrit-Project: kudu
Gerrit-Branch: master
Gerrit-MessageType: newpatchset
Gerrit-Change-Id: If59d831240af15bfa7ef5709ec3d105d13b28322
Gerrit-Change-Number: 12197
Gerrit-PatchSet: 2
Gerrit-Owner: Adar Dembo <ad...@cloudera.com>
Gerrit-Reviewer: Grant Henke <gr...@apache.org>
Gerrit-Reviewer: Kudu Jenkins (120)
Gerrit-Reviewer: Mike Percy <mp...@apache.org>
Gerrit-Reviewer: Todd Lipcon <to...@apache.org>

[kudu-CR] generic iterators: basic MergeIterator dominance

Posted by "Adar Dembo (Code Review)" <ge...@cloudera.org>.
Adar Dembo has posted comments on this change. ( http://gerrit.cloudera.org:8080/12197 )

Change subject: generic_iterators: basic MergeIterator dominance
......................................................................


Patch Set 6:

(4 comments)

http://gerrit.cloudera.org:8080/#/c/12197/5//COMMIT_MSG
Commit Message:

http://gerrit.cloudera.org:8080/#/c/12197/5//COMMIT_MSG@11
PS5, Line 11: omit sub-iterator A if its current block's first primary key is
            : lexicographically greater than another sub-iterator B's current block
> is this phrased backwards? ie:
Whoops, yes.


http://gerrit.cloudera.org:8080/#/c/12197/5/src/kudu/common/generic_iterators.cc
File src/kudu/common/generic_iterators.cc:

http://gerrit.cloudera.org:8080/#/c/12197/5/src/kudu/common/generic_iterators.cc@536
PS5, Line 536:   size_t available = 0;
> is it worth adding:
Sounds reasonable.


http://gerrit.cloudera.org:8080/#/c/12197/5/src/kudu/common/generic_iterators.cc@593
PS5, Line 593:                                 [](MergeIterState* s) { delete s; });
> if the dominated iterators were stored as a min-heap by their min_key, this
As we discussed offline, I'm going to evaluate this as part of a follow-up patch, so I can see what kind of effect it has in isolation.


http://gerrit.cloudera.org:8080/#/c/12197/5/src/kudu/common/generic_iterators.cc@606
PS5, Line 606:       // 2. However, pulling a new block can't cause 'smallest' to dominate any
> similarly here if we have a heap of states_ we could O(1) find the state_ w
See above.



-- 
To view, visit http://gerrit.cloudera.org:8080/12197
To unsubscribe, visit http://gerrit.cloudera.org:8080/settings

Gerrit-Project: kudu
Gerrit-Branch: master
Gerrit-MessageType: comment
Gerrit-Change-Id: If59d831240af15bfa7ef5709ec3d105d13b28322
Gerrit-Change-Number: 12197
Gerrit-PatchSet: 6
Gerrit-Owner: Adar Dembo <ad...@cloudera.com>
Gerrit-Reviewer: Adar Dembo <ad...@cloudera.com>
Gerrit-Reviewer: Grant Henke <gr...@apache.org>
Gerrit-Reviewer: Kudu Jenkins (120)
Gerrit-Reviewer: Mike Percy <mp...@apache.org>
Gerrit-Reviewer: Todd Lipcon <to...@apache.org>
Gerrit-Comment-Date: Mon, 14 Jan 2019 21:03:58 +0000
Gerrit-HasComments: Yes