Skip to content

Header iterator memory optimization in HeaderGroup - #694

Open
ok2c wants to merge 4 commits into
apache:masterfrom
ok2c:header_iterator_optimization
Open

Header iterator memory optimization in HeaderGroup#694
ok2c wants to merge 4 commits into
apache:masterfrom
ok2c:header_iterator_optimization

Conversation

@ok2c

@ok2c ok2c commented Sep 4, 2026

Copy link
Copy Markdown
Member

@arturobernalg Please double-check / review

@ok2c
ok2c requested a review from arturobernalg September 4, 2026 17:39
this.lastIndex = -1;
}

BasicListHeaderIterator(final List<? extends Header> headers, final int currentIndex, final String name) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ok2c
The new BasicListHeaderIterator constructor does not initialize lastIndex, so it defaults to 0. Calling remove() before next() then removes the first header instead of throwing IllegalStateException. I confirmed it with a regression test. Initializing lastIndex to -1 fixes it.

Otherwise, the change looks good to me.

Test that prove.


@Test
void testIteratorByNameRemoveBeforeNext() {
    final HeaderGroup headerGroup = new HeaderGroup();
    final Header headerA = new BasicHeader("a", "a-one");
    final Header headerB = new BasicHeader("b", "b-one");
    headerGroup.setHeaders(headerA, headerB);

    final Iterator<Header> iterator = headerGroup.headerIterator("b");

    Assertions.assertThrows(IllegalStateException.class, iterator::remove);
    Assertions.assertArrayEquals(
            new Header[] { headerA, headerB },
            headerGroup.getHeaders());
}

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@arturobernalg Good catch! Thank you! Please do another pass. I have also made a few small improvements and optimizations and have added test coverage. Those tests can also serve as an example of how to parse messages efficiently

@ok2c
ok2c force-pushed the header_iterator_optimization branch from 26d8ba4 to d16909e Compare September 8, 2026 15:09

@arturobernalg arturobernalg left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ok2c The previous implementation inherited argument validation from parseElementList(). With the direct parsing loop those checks are lost.

Could we preserve the existing contract here?

Args.notNull(src, "Source");
Args.notNull(cursor, "Cursor");
Args.notNull(consumer, "Consumer");

Otherwise look good

@ok2c

ok2c commented Sep 9, 2026

Copy link
Copy Markdown
Member Author

@ok2c The previous implementation inherited argument validation from parseElementList(). With the direct parsing loop those checks are lost.

Could we preserve the existing contract here?

@arturobernalg I can do that, but would that be really useful? This is a package private constructor not exposed through public APIs and not callable outside of the same package. What good would those checks do?

@arturobernalg

Copy link
Copy Markdown
Member

@ok2c The previous implementation inherited argument validation from parseElementList(). With the direct parsing loop those checks are lost.
Could we preserve the existing contract here?

@arturobernalg I can do that, but would that be really useful? This is a package private constructor not exposed through public APIs and not callable outside of the same package. What good would those checks do?

@ok2c Fair enough

@arturobernalg arturobernalg left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The previous implementation inherited argument validation from parseElementList(). With the direct parsing loop those checks are lost.

Could we preserve the existing contract here?

Args.notNull(src, "Source");
Args.notNull(cursor, "Cursor");
Args.notNull(consumer, "Consumer");

Otherwise look good

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants