24
24
import org .apache .lucene .search .MatchAllDocsQuery ;
25
25
import org .apache .lucene .search .Query ;
26
26
import org .apache .lucene .util .BytesRef ;
27
+ import org .apache .lucene .util .BytesRefBuilder ;
27
28
import org .elasticsearch .common .CheckedFunction ;
29
+ import org .elasticsearch .common .lease .Releasables ;
30
+ import org .elasticsearch .common .util .BigArrays ;
31
+ import org .elasticsearch .common .util .ObjectArray ;
28
32
import org .elasticsearch .index .fielddata .SortedBinaryDocValues ;
29
- import org .elasticsearch .index .mapper .KeywordFieldMapper ;
30
33
import org .elasticsearch .index .mapper .MappedFieldType ;
31
34
import org .elasticsearch .index .mapper .StringFieldType ;
32
- import org .elasticsearch .index .mapper .TextFieldMapper ;
33
35
import org .elasticsearch .search .DocValueFormat ;
34
36
import org .elasticsearch .search .aggregations .LeafBucketCollector ;
35
37
36
38
import java .io .IOException ;
39
+ import java .util .function .LongConsumer ;
37
40
38
41
/**
39
42
* A {@link SingleDimensionValuesSource} for binary source ({@link BytesRef}).
40
43
*/
41
44
class BinaryValuesSource extends SingleDimensionValuesSource <BytesRef > {
45
+ private final LongConsumer breakerConsumer ;
42
46
private final CheckedFunction <LeafReaderContext , SortedBinaryDocValues , IOException > docValuesFunc ;
43
- private final BytesRef [] values ;
47
+ private ObjectArray <BytesRef > values ;
48
+ private ObjectArray <BytesRefBuilder > valueBuilders ;
44
49
private BytesRef currentValue ;
45
50
46
- BinaryValuesSource (MappedFieldType fieldType , CheckedFunction <LeafReaderContext , SortedBinaryDocValues , IOException > docValuesFunc ,
47
- DocValueFormat format , Object missing , int size , int reverseMul ) {
48
- super (format , fieldType , missing , size , reverseMul );
51
+ BinaryValuesSource (BigArrays bigArrays , LongConsumer breakerConsumer ,
52
+ MappedFieldType fieldType , CheckedFunction <LeafReaderContext , SortedBinaryDocValues , IOException > docValuesFunc ,
53
+ DocValueFormat format , boolean missingBucket , Object missing , int size , int reverseMul ) {
54
+ super (bigArrays , format , fieldType , missingBucket , missing , size , reverseMul );
55
+ this .breakerConsumer = breakerConsumer ;
49
56
this .docValuesFunc = docValuesFunc ;
50
- this .values = new BytesRef [size ];
57
+ this .values = bigArrays .newObjectArray (Math .min (size , 100 ));
58
+ this .valueBuilders = bigArrays .newObjectArray (Math .min (size , 100 ));
51
59
}
52
60
53
61
@ Override
54
- public void copyCurrent (int slot ) {
55
- values [slot ] = BytesRef .deepCopyOf (currentValue );
62
+ void copyCurrent (int slot ) {
63
+ values = bigArrays .grow (values , slot +1 );
64
+ valueBuilders = bigArrays .grow (valueBuilders , slot +1 );
65
+ BytesRefBuilder builder = valueBuilders .get (slot );
66
+ int byteSize = builder == null ? 0 : builder .bytes ().length ;
67
+ if (builder == null ) {
68
+ builder = new BytesRefBuilder ();
69
+ valueBuilders .set (slot , builder );
70
+ }
71
+ if (missingBucket && currentValue == null ) {
72
+ values .set (slot , null );
73
+ } else {
74
+ assert currentValue != null ;
75
+ builder .copyBytes (currentValue );
76
+ breakerConsumer .accept (builder .bytes ().length - byteSize );
77
+ values .set (slot , builder .get ());
78
+ }
56
79
}
57
80
58
81
@ Override
59
- public int compare (int from , int to ) {
60
- return compareValues (values [from ], values [to ]);
82
+ int compare (int from , int to ) {
83
+ if (missingBucket ) {
84
+ if (values .get (from ) == null ) {
85
+ return values .get (to ) == null ? 0 : -1 * reverseMul ;
86
+ } else if (values .get (to ) == null ) {
87
+ return reverseMul ;
88
+ }
89
+ }
90
+ return compareValues (values .get (from ), values .get (to ));
61
91
}
62
92
63
93
@ Override
64
94
int compareCurrent (int slot ) {
65
- return compareValues (currentValue , values [slot ]);
95
+ if (missingBucket ) {
96
+ if (currentValue == null ) {
97
+ return values .get (slot ) == null ? 0 : -1 * reverseMul ;
98
+ } else if (values .get (slot ) == null ) {
99
+ return reverseMul ;
100
+ }
101
+ }
102
+ return compareValues (currentValue , values .get (slot ));
66
103
}
67
104
68
105
@ Override
69
106
int compareCurrentWithAfter () {
107
+ if (missingBucket ) {
108
+ if (currentValue == null ) {
109
+ return afterValue == null ? 0 : -1 * reverseMul ;
110
+ } else if (afterValue == null ) {
111
+ return reverseMul ;
112
+ }
113
+ }
70
114
return compareValues (currentValue , afterValue );
71
115
}
72
116
@@ -76,7 +120,9 @@ int compareValues(BytesRef v1, BytesRef v2) {
76
120
77
121
@ Override
78
122
void setAfter (Comparable <?> value ) {
79
- if (value .getClass () == String .class ) {
123
+ if (missingBucket && value == null ) {
124
+ afterValue = null ;
125
+ } else if (value .getClass () == String .class ) {
80
126
afterValue = format .parseBytesRef (value .toString ());
81
127
} else {
82
128
throw new IllegalArgumentException ("invalid value, expected string, got " + value .getClass ().getSimpleName ());
@@ -85,7 +131,7 @@ void setAfter(Comparable<?> value) {
85
131
86
132
@ Override
87
133
BytesRef toComparable (int slot ) {
88
- return values [ slot ] ;
134
+ return values . get ( slot ) ;
89
135
}
90
136
91
137
@ Override
@@ -100,6 +146,9 @@ public void collect(int doc, long bucket) throws IOException {
100
146
currentValue = dvs .nextValue ();
101
147
next .collect (doc , bucket );
102
148
}
149
+ } else if (missingBucket ) {
150
+ currentValue = null ;
151
+ next .collect (doc , bucket );
103
152
}
104
153
}
105
154
};
@@ -130,5 +179,7 @@ SortedDocsProducer createSortedDocsProducerOrNull(IndexReader reader, Query quer
130
179
}
131
180
132
181
@ Override
133
- public void close () {}
182
+ public void close () {
183
+ Releasables .close (values , valueBuilders );
184
+ }
134
185
}
0 commit comments