2323
2424import org .eclipse .rdf4j .common .annotation .InternalUseOnly ;
2525import org .eclipse .rdf4j .model .Value ;
26+ import org .eclipse .rdf4j .model .util .Values ;
2627import org .eclipse .rdf4j .query .AbstractBindingSet ;
2728import org .eclipse .rdf4j .query .Binding ;
2829import org .eclipse .rdf4j .query .BindingSet ;
@@ -42,15 +43,15 @@ public class ArrayBindingSet extends AbstractBindingSet implements MutableBindin
4243 private static final long serialVersionUID = -1L ;
4344
4445 private static final Logger logger = LoggerFactory .getLogger (ArrayBindingSet .class );
46+ private static final Value NULL_VALUE = Values
47+ .iri ("urn:null:d57c56f3-41a9-468e-8dce-5706ebdef84c_e88d9e52-27cb-4056-a889-1ea353fa6f0c" );
4548
4649 private final String [] bindingNames ;
4750
4851 // Creating a LinkedHashSet is expensive, so we should cache the binding names set
4952 private Set <String > bindingNamesSetCache ;
5053 private boolean empty ;
5154
52- private final boolean [] whichBindingsHaveBeenSet ;
53-
5455 private final Value [] values ;
5556
5657 /**
@@ -63,21 +64,24 @@ public class ArrayBindingSet extends AbstractBindingSet implements MutableBindin
6364 public ArrayBindingSet (String ... names ) {
6465 this .bindingNames = names ;
6566 this .values = new Value [names .length ];
66- this .whichBindingsHaveBeenSet = new boolean [names .length ];
6767 this .empty = true ;
6868 }
6969
7070 public ArrayBindingSet (BindingSet toCopy , Set <String > names , String [] namesArray ) {
7171 assert !(toCopy instanceof ArrayBindingSet );
7272
7373 this .bindingNames = namesArray ;
74- this .whichBindingsHaveBeenSet = new boolean [this .bindingNames .length ];
7574 this .values = new Value [this .bindingNames .length ];
7675 for (int i = 0 ; i < this .bindingNames .length ; i ++) {
7776 Binding binding = toCopy .getBinding (this .bindingNames [i ]);
77+
7878 if (binding != null ) {
7979 this .values [i ] = binding .getValue ();
80- this .whichBindingsHaveBeenSet [i ] = true ;
80+ if (this .values [i ] == null ) {
81+ this .values [i ] = NULL_VALUE ;
82+ }
83+ } else if (hasBinding (this .bindingNames [i ])) {
84+ this .values [i ] = NULL_VALUE ;
8185 }
8286 }
8387 this .empty = toCopy .isEmpty ();
@@ -89,8 +93,6 @@ public ArrayBindingSet(ArrayBindingSet toCopy, String... names) {
8993 this .bindingNames = names ;
9094
9195 this .values = Arrays .copyOf (toCopy .values , toCopy .values .length );
92- this .whichBindingsHaveBeenSet = Arrays .copyOf (toCopy .whichBindingsHaveBeenSet ,
93- toCopy .whichBindingsHaveBeenSet .length );
9496 this .empty = toCopy .empty ;
9597 assert !this .empty || size () == 0 ;
9698 }
@@ -111,8 +113,7 @@ public BiConsumer<Value, ArrayBindingSet> getDirectSetBinding(String bindingName
111113 return null ;
112114 }
113115 return (v , a ) -> {
114- a .values [index ] = v ;
115- a .whichBindingsHaveBeenSet [index ] = true ;
116+ a .values [index ] = v == null ? NULL_VALUE : v ;
116117 a .empty = false ;
117118 a .clearCache ();
118119 };
@@ -126,9 +127,8 @@ public BiConsumer<Value, ArrayBindingSet> getDirectAddBinding(String bindingName
126127 return null ;
127128 }
128129 return (v , a ) -> {
129- assert !a .whichBindingsHaveBeenSet [index ] : "variable already bound: " + bindingName ;
130- a .values [index ] = v ;
131- a .whichBindingsHaveBeenSet [index ] = true ;
130+ assert a .values [index ] == null ;
131+ a .values [index ] = v == null ? NULL_VALUE : v ;
132132 a .empty = false ;
133133 a .clearCache ();
134134 };
@@ -143,6 +143,9 @@ public Function<ArrayBindingSet, Binding> getDirectGetBinding(String bindingName
143143 }
144144 return a -> {
145145 Value value = a .values [index ];
146+ if (value == NULL_VALUE ) {
147+ value = null ;
148+ }
146149 if (value != null ) {
147150 return new SimpleBinding (bindingName , value );
148151 } else {
@@ -157,7 +160,7 @@ public Function<ArrayBindingSet, Value> getDirectGetValue(String bindingName) {
157160 if (index == -1 ) {
158161 return null ;
159162 }
160- return a -> a .values [index ];
163+ return a -> a .values [index ] == NULL_VALUE ? null : a . values [ index ] ;
161164
162165 }
163166
@@ -166,7 +169,7 @@ public Function<ArrayBindingSet, Boolean> getDirectHasBinding(String bindingName
166169 if (index == -1 ) {
167170 return null ;
168171 }
169- return a -> a .whichBindingsHaveBeenSet [index ];
172+ return a -> a .values [index ] != null ;
170173 }
171174
172175 private int getIndex (String bindingName ) {
@@ -195,7 +198,7 @@ public Set<String> getBindingNames() {
195198 this .bindingNamesSetCache = Collections .emptySet ();
196199 } else if (size == 1 ) {
197200 for (int i = 0 ; i < this .bindingNames .length ; i ++) {
198- if (whichBindingsHaveBeenSet [i ]) {
201+ if (values [i ] != null ) {
199202 this .bindingNamesSetCache = Collections .singleton (bindingNames [i ]);
200203 break ;
201204 }
@@ -204,7 +207,7 @@ public Set<String> getBindingNames() {
204207 } else {
205208 LinkedHashSet <String > bindingNamesSetCache = new LinkedHashSet <>(size * 2 );
206209 for (int i = 0 ; i < this .bindingNames .length ; i ++) {
207- if (whichBindingsHaveBeenSet [i ]) {
210+ if (values [i ] != null ) {
208211 bindingNamesSetCache .add (bindingNames [i ]);
209212 }
210213 }
@@ -222,14 +225,14 @@ public Value getValue(String bindingName) {
222225 }
223226
224227 for (int i = 0 ; i < bindingNames .length ; i ++) {
225- if (bindingNames [i ] == bindingName && whichBindingsHaveBeenSet [i ]) {
226- return values [i ];
228+ if (bindingNames [i ] == bindingName && values [i ] != null ) {
229+ return values [i ] == NULL_VALUE ? null : values [ i ] ;
227230 }
228231 }
229232
230233 for (int i = 0 ; i < bindingNames .length ; i ++) {
231- if (bindingNames [i ].equals (bindingName ) && whichBindingsHaveBeenSet [i ]) {
232- return values [i ];
234+ if (bindingNames [i ].equals (bindingName ) && values [i ] != null ) {
235+ return values [i ] == NULL_VALUE ? null : values [ i ] ;
233236 }
234237 }
235238 return null ;
@@ -242,6 +245,9 @@ public Binding getBinding(String bindingName) {
242245 }
243246
244247 Value value = getValue (bindingName );
248+ if (value == NULL_VALUE ) {
249+ value = null ;
250+ }
245251
246252 if (value != null ) {
247253 return new SimpleBinding (bindingName , value );
@@ -260,7 +266,7 @@ public boolean hasBinding(String bindingName) {
260266 if (index == -1 ) {
261267 return false ;
262268 }
263- return whichBindingsHaveBeenSet [index ];
269+ return values [index ] != null ;
264270 }
265271
266272 @ Override
@@ -280,8 +286,8 @@ public int size() {
280286
281287 int size = 0 ;
282288
283- for (boolean value : whichBindingsHaveBeenSet ) {
284- if (value ) {
289+ for (Value value : values ) {
290+ if (value != null ) {
285291 size ++;
286292 }
287293 }
@@ -298,14 +304,14 @@ public List<String> getSortedBindingNames() {
298304
299305 if (size == 1 ) {
300306 for (int i = 0 ; i < bindingNames .length ; i ++) {
301- if (whichBindingsHaveBeenSet [i ]) {
307+ if (values [i ] != null ) {
302308 sortedBindingNames = Collections .singletonList (bindingNames [i ]);
303309 }
304310 }
305311 } else {
306312 ArrayList <String > names = new ArrayList <>(size );
307313 for (int i = 0 ; i < bindingNames .length ; i ++) {
308- if (whichBindingsHaveBeenSet [i ]) {
314+ if (values [i ] != null ) {
309315 names .add (bindingNames [i ]);
310316 }
311317 }
@@ -320,17 +326,17 @@ public List<String> getSortedBindingNames() {
320326 @ Override
321327 public void addBinding (Binding binding ) {
322328 int index = getIndex (binding .getName ());
329+ Value value = binding .getValue ();
323330 if (index == -1 ) {
324331 logger .error (
325- "We don't actually support adding a binding. " + binding .getName () + " : " + binding . getValue () );
332+ "We don't actually support adding a binding. " + binding .getName () + " : " + value );
326333 assert false
327- : "We don't actually support adding a binding. " + binding .getName () + " : " + binding . getValue () ;
334+ : "We don't actually support adding a binding. " + binding .getName () + " : " + value ;
328335 return ;
329336 }
330337
331- assert !this .whichBindingsHaveBeenSet [index ];
332- this .values [index ] = binding .getValue ();
333- this .whichBindingsHaveBeenSet [index ] = true ;
338+ assert this .values [index ] == null ;
339+ this .values [index ] = value == null ? NULL_VALUE : value ;
334340 empty = false ;
335341 clearCache ();
336342 }
@@ -341,8 +347,8 @@ public void setBinding(Binding binding) {
341347 if (index == -1 ) {
342348 return ;
343349 }
344- this . values [ index ] = binding .getValue ();
345- this .whichBindingsHaveBeenSet [index ] = true ;
350+ Value value = binding .getValue ();
351+ this .values [index ] = value == null ? NULL_VALUE : value ;
346352 empty = false ;
347353 clearCache ();
348354 }
@@ -355,11 +361,10 @@ public void setBinding(String name, Value value) {
355361 }
356362
357363 this .values [index ] = value ;
358- this .whichBindingsHaveBeenSet [index ] = value != null ;
359364 if (value == null ) {
360365 this .empty = true ;
361- for (boolean b : whichBindingsHaveBeenSet ) {
362- if (b ) {
366+ for (Value value1 : this . values ) {
367+ if (value1 != null ) {
363368 this .empty = false ;
364369 break ;
365370 }
@@ -382,17 +387,16 @@ private void clearCache() {
382387 public void addAll (ArrayBindingSet other ) {
383388 if (other .bindingNames == bindingNames ) {
384389 for (int i = 0 ; i < bindingNames .length ; i ++) {
385- if (other .whichBindingsHaveBeenSet [i ]) {
390+ if (other .values [i ] != null ) {
386391 this .values [i ] = other .values [i ];
387- this .whichBindingsHaveBeenSet [i ] = true ;
388392 this .empty = false ;
389393 }
390394 }
391395 } else {
392396 for (int i = 0 ; i < bindingNames .length ; i ++) {
393397 if (other .hasBinding (bindingNames [i ])) {
394- this . values [ i ] = other .getValue (bindingNames [i ]);
395- this .whichBindingsHaveBeenSet [i ] = true ;
398+ Value value = other .getValue (bindingNames [i ]);
399+ this .values [i ] = value == null ? NULL_VALUE : value ;
396400 this .empty = false ;
397401 }
398402 }
@@ -412,7 +416,7 @@ public ArrayBindingSetIterator() {
412416 @ Override
413417 public boolean hasNext () {
414418 while (index < values .length ) {
415- if (whichBindingsHaveBeenSet [index ]) {
419+ if (values [index ] != null ) {
416420 return true ;
417421 }
418422 index ++;
@@ -423,9 +427,12 @@ public boolean hasNext() {
423427 @ Override
424428 public Binding next () {
425429 while (index < values .length ) {
426- if (whichBindingsHaveBeenSet [index ]) {
430+ if (values [index ] != null ) {
427431 String name = bindingNames [index ];
428432 Value value = values [index ++];
433+ if (value == NULL_VALUE ) {
434+ value = null ;
435+ }
429436 if (value != null ) {
430437 return new SimpleBinding (name , value );
431438 } else {
0 commit comments