-
Notifications
You must be signed in to change notification settings - Fork 9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RavenDB-22088 - reduce the lock contention in SegmentReader #67
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -191,10 +191,16 @@ internal Directory GetCFSReader() | |||||||||||||
return cfsReader; | ||||||||||||||
} | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
internal TermInfosReader GetTermsReader() | ||||||||||||||
{ | ||||||||||||||
lock (this) | ||||||||||||||
{ | ||||||||||||||
// This is initialized in the constructor. | ||||||||||||||
// The only time it isn't initialized is when termsIndexDivisor equals -1, which we don't use. | ||||||||||||||
var reader = tis; | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What if There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can still get a reference to it and after that it will be disposed. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In current impl if lucenenet/src/Lucene.Net/Index/SegmentReader.cs Lines 261 to 266 in 34bc333
then we return After the change made here we can return There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can get a reference to it (when calling There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The original code doesn't protect you from getting a |
||||||||||||||
if (reader != null) | ||||||||||||||
return reader; | ||||||||||||||
|
||||||||||||||
lock (this) | ||||||||||||||
{ | ||||||||||||||
if (tis != null) | ||||||||||||||
{ | ||||||||||||||
|
@@ -208,20 +214,21 @@ internal TermInfosReader GetTermsReader() | |||||||||||||
} | ||||||||||||||
|
||||||||||||||
internal bool TermsIndexIsLoaded() | ||||||||||||||
{ | ||||||||||||||
lock (this) | ||||||||||||||
{ | ||||||||||||||
return tis != null; | ||||||||||||||
} | ||||||||||||||
{ | ||||||||||||||
// If this is null, we call LoadTermsIndex, which uses a lock. | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please note that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The lock is there because this method isn't thread safe. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. And your change made it even more not thread save, didn't it? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The |
||||||||||||||
return tis != null; | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
// NOTE: only called from IndexWriter when a near | ||||||||||||||
// real-time reader is opened, or applyDeletes is run, | ||||||||||||||
// sharing a segment that's still being merged. This | ||||||||||||||
// method is not fully thread safe, and relies on the | ||||||||||||||
// synchronization in IndexWriter | ||||||||||||||
internal void LoadTermsIndex(SegmentInfo si, int termsIndexDivisor, IState state) | ||||||||||||||
{ | ||||||||||||||
internal void LoadTermsIndex(SegmentInfo si, int termsIndexDivisor, IState state) | ||||||||||||||
{ | ||||||||||||||
if (tis != null) | ||||||||||||||
return; | ||||||||||||||
|
||||||||||||||
lock (this) | ||||||||||||||
{ | ||||||||||||||
if (tis == null) | ||||||||||||||
|
@@ -310,7 +317,10 @@ internal void DecRef() | |||||||||||||
} | ||||||||||||||
|
||||||||||||||
internal void OpenDocStores(SegmentInfo si, IState state) | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Was this method also affected (and you saw that in the stacktraces) or you modified it "just in case" because it might have the same issue? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I added |
||||||||||||||
{ | ||||||||||||||
{ | ||||||||||||||
if (fieldsReaderOrig != null) | ||||||||||||||
return; | ||||||||||||||
|
||||||||||||||
lock (this) | ||||||||||||||
{ | ||||||||||||||
|
||||||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What we don't use? Can you elaborate on that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
TermInfosReader
holds an array of sorted, cached terms and their positions (note that this cache does not include all terms) to efficiently locate the correct term during searches.The algorithm is roughly the following:
We use binary search to find the position of the closest term within the sorted cache.
lucenenet/src/Lucene.Net/Index/TermInfosReader.cs
Line 194 in 34bc333
We then iterate until we find the exact match.
lucenenet/src/Lucene.Net/Index/SegmentTermEnum.cs
Line 184 in 34bc333
The size of the cache is determined by the
termsIndexDivisor
. A larger number creates a smaller cache, requiring more time to find the correct term but reducing memory usage.The default value is
1
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's hard for me understand the answer. I was rather expecting you to tell my why is it the case that in our scenarios
termsIndexDivisor
is never-1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can confirm that it can never be
-1
:lucenenet/src/Lucene.Net/Index/IndexWriter.cs
Line 1522 in 34bc333