Skip to content

Commit faf2da5

Browse files
committed
Merge pull request #2 from CarlRaymond/master
Reimplemented ChainedFilter and EnumerableBasedDocIdSetIterator
2 parents 3aac5d3 + 7ba0359 commit faf2da5

File tree

2 files changed

+139
-152
lines changed

2 files changed

+139
-152
lines changed

src/.nuget/NuGet.targets

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
<RequireRestoreConsent Condition=" '$(RequireRestoreConsent)' != 'false' ">true</RequireRestoreConsent>
1414

1515
<!-- Download NuGet.exe if it does not already exist -->
16-
<DownloadNuGetExe Condition=" '$(DownloadNuGetExe)' == '' ">false</DownloadNuGetExe>
16+
<DownloadNuGetExe Condition=" '$(DownloadNuGetExe)' == '' ">true</DownloadNuGetExe>
1717
</PropertyGroup>
1818

1919
<ItemGroup Condition=" '$(PackageSources)' == '' ">

src/NHibernate.Search/Filter/ChainedFilter.cs

Lines changed: 138 additions & 151 deletions
Original file line numberDiff line numberDiff line change
@@ -9,157 +9,144 @@ namespace NHibernate.Search.Filter
99
using Lucene.Net.Index;
1010
using Lucene.Net.Search;
1111

12+
/// <summary>
13+
/// A filter that performs a Boolean AND on multiple filters.
14+
/// </summary>
1215
public class ChainedFilter : Filter
1316
{
14-
private readonly List<Filter> chainedFilters = new List<Filter>();
15-
16-
public void AddFilter(Filter filter)
17-
{
18-
chainedFilters.Add(filter);
19-
}
20-
21-
public override DocIdSet GetDocIdSet(IndexReader reader)
22-
{
23-
if (chainedFilters.Count == 0)
24-
{
25-
throw new AssertionFailure("ChainedFilter has no filters to chain for");
26-
}
27-
28-
// We need to copy the first BitArray because BitArray is assigned to by And
29-
HashSet<int> result = null;
30-
31-
foreach (var filter in chainedFilters)
32-
{
33-
DocIdSet b2 = filter.GetDocIdSet(reader);
34-
int docId;
35-
DocIdSetIterator iterator = b2.Iterator();
36-
37-
if (result == null)
38-
{
39-
result = new HashSet<int>();
40-
41-
while ((docId = iterator.NextDoc()) != DocIdSetIterator.NO_MORE_DOCS)
42-
{
43-
result.Add(docId);
44-
}
45-
}
46-
else
47-
{
48-
while ((docId = iterator.NextDoc()) != DocIdSetIterator.NO_MORE_DOCS)
49-
{
50-
if (!result.Contains(docId))
51-
{
52-
result.Remove(docId);
53-
}
54-
}
55-
}
56-
}
57-
58-
DocIdSet filteredCombinedDocIdSet = new EnumerableBasedDocIdSet(result);
59-
return filteredCombinedDocIdSet;
60-
}
61-
62-
public override string ToString()
63-
{
64-
StringBuilder sb = new StringBuilder("ChainedFilter [");
65-
foreach (Filter filter in chainedFilters)
66-
{
67-
sb.AppendLine().Append(filter.ToString());
68-
}
69-
70-
return sb.Append("\r\n]").ToString();
71-
}
72-
}
73-
74-
public class EnumerableBasedDocIdSet : DocIdSet
75-
{
76-
private readonly IEnumerable<int> _items;
77-
78-
public EnumerableBasedDocIdSet(IEnumerable<int> items)
79-
{
80-
if (items == null)
81-
{
82-
throw new ArgumentNullException("items");
83-
}
84-
85-
_items = items;
86-
}
87-
88-
/// <summary>
89-
/// Provides a <see cref="T:Lucene.Net.Search.DocIdSetIterator"/> to access the set.
90-
/// This implementation can return <c>null</c> or
91-
/// <c>EMPTY_DOCIDSET.Iterator()</c> if there
92-
/// are no docs that match.
93-
/// </summary>
94-
public override DocIdSetIterator Iterator()
95-
{
96-
return new EnumerableBasedDocIdSetIterator(_items);
97-
}
98-
}
99-
100-
public class EnumerableBasedDocIdSetIterator : DocIdSetIterator
101-
{
102-
private readonly IEnumerable<int> items;
103-
private IEnumerator<int> iterator;
104-
private int? currentIndex;
105-
106-
public EnumerableBasedDocIdSetIterator(IEnumerable<int> items)
107-
{
108-
if (items == null)
109-
{
110-
throw new ArgumentNullException("items");
111-
}
112-
113-
this.items = items;
114-
iterator = items.GetEnumerator();
115-
}
116-
117-
public override int Advance(int target)
118-
{
119-
if (currentIndex == null)
120-
{
121-
currentIndex = 0;
122-
}
123-
124-
if (target < currentIndex)
125-
{
126-
throw new ArgumentOutOfRangeException("target", target, "Iterator state past target: " + currentIndex);
127-
}
128-
129-
int remaining = target - currentIndex.Value;
130-
bool hasMore;
131-
132-
while ((hasMore = iterator.MoveNext()) && remaining > 0)
133-
{
134-
currentIndex++;
135-
}
136-
137-
if (!hasMore)
138-
{
139-
currentIndex = NO_MORE_DOCS;
140-
}
141-
142-
return currentIndex == NO_MORE_DOCS ? NO_MORE_DOCS : iterator.Current;
143-
}
144-
145-
public override int DocID()
146-
{
147-
if (currentIndex == NO_MORE_DOCS || currentIndex == null)
148-
{
149-
return NO_MORE_DOCS;
150-
}
151-
152-
return iterator.Current;
153-
}
154-
155-
public override int NextDoc()
156-
{
157-
if (currentIndex == NO_MORE_DOCS)
158-
{
159-
return NO_MORE_DOCS;
160-
}
161-
162-
return Advance(currentIndex.Value + 1);
163-
}
164-
}
17+
private readonly List<Filter> chainedFilters = new List<Filter>();
18+
19+
public void AddFilter(Filter filter)
20+
{
21+
chainedFilters.Add(filter);
22+
}
23+
24+
private HashSet<int> DocIdSetToHashSet(DocIdSet docs)
25+
{
26+
var result = new HashSet<int>();
27+
var iterator = docs.Iterator();
28+
29+
int docId;
30+
while ((docId = iterator.NextDoc()) != DocIdSetIterator.NO_MORE_DOCS)
31+
result.Add(docId);
32+
33+
return result;
34+
}
35+
36+
public override DocIdSet GetDocIdSet(IndexReader reader)
37+
{
38+
if (chainedFilters.Count == 0)
39+
{
40+
throw new AssertionFailure("ChainedFilter has no filters to chain for");
41+
}
42+
43+
// Create HashSet of first filter's contents
44+
HashSet<int> result = DocIdSetToHashSet(chainedFilters[0].GetDocIdSet(reader));
45+
46+
// For each remaining filter, fill another HashSet and intersect it with the first.
47+
for (int i = 1; i < chainedFilters.Count; i++)
48+
{
49+
var nextSet = DocIdSetToHashSet(chainedFilters[i].GetDocIdSet(reader));
50+
result.IntersectWith(nextSet);
51+
}
52+
53+
DocIdSet resultDocIds = new EnumerableBasedDocIdSet(result);
54+
return resultDocIds;
55+
}
56+
57+
58+
public override string ToString()
59+
{
60+
StringBuilder sb = new StringBuilder("ChainedFilter [");
61+
foreach (Filter filter in chainedFilters)
62+
{
63+
sb.AppendLine().Append(filter.ToString());
64+
}
65+
66+
return sb.Append("\r\n]").ToString();
67+
}
68+
}
69+
70+
public class EnumerableBasedDocIdSet : DocIdSet
71+
{
72+
private readonly IEnumerable<int> _items;
73+
74+
public EnumerableBasedDocIdSet(IEnumerable<int> items)
75+
{
76+
if (items == null)
77+
{
78+
throw new ArgumentNullException("items");
79+
}
80+
81+
_items = items;
82+
}
83+
84+
/// <summary>
85+
/// Provides a <see cref="T:Lucene.Net.Search.DocIdSetIterator"/> to access the set.
86+
/// This implementation can return <c>null</c> or
87+
/// <c>EMPTY_DOCIDSET.Iterator()</c> if there
88+
/// are no docs that match.
89+
/// </summary>
90+
public override DocIdSetIterator Iterator()
91+
{
92+
return new EnumerableBasedDocIdSetIterator(_items);
93+
}
94+
}
95+
96+
public class EnumerableBasedDocIdSetIterator : DocIdSetIterator
97+
{
98+
private readonly IEnumerable<int> items;
99+
private IEnumerator<int> iterator;
100+
private int currentIndex = -1;
101+
102+
public EnumerableBasedDocIdSetIterator(IEnumerable<int> items)
103+
{
104+
if (items == null)
105+
{
106+
throw new ArgumentNullException("items");
107+
}
108+
109+
this.items = items;
110+
iterator = items.GetEnumerator();
111+
}
112+
113+
public override int Advance(int target)
114+
{
115+
if (target < currentIndex)
116+
{
117+
throw new ArgumentOutOfRangeException("target", target, "Iterator state past target: " + currentIndex);
118+
}
119+
120+
// Relies on NO_MORE_DOCS being a big number
121+
while (target > currentIndex)
122+
{
123+
if (iterator.MoveNext())
124+
currentIndex++;
125+
else
126+
currentIndex = NO_MORE_DOCS;
127+
}
128+
129+
return currentIndex == NO_MORE_DOCS ? NO_MORE_DOCS : iterator.Current;
130+
}
131+
132+
public override int DocID()
133+
{
134+
if (currentIndex == NO_MORE_DOCS || currentIndex == -1)
135+
{
136+
return NO_MORE_DOCS;
137+
}
138+
139+
return iterator.Current;
140+
}
141+
142+
public override int NextDoc()
143+
{
144+
if (currentIndex == NO_MORE_DOCS)
145+
{
146+
return NO_MORE_DOCS;
147+
}
148+
149+
return Advance(currentIndex + 1);
150+
}
151+
}
165152
}

0 commit comments

Comments
 (0)