/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.jena.mem;
import java.util.function.Function ;
import org.apache.jena.shared.BrokenException ;
/**
An implementation of BunchMap that does open-addressed hashing.
*/
public class HashedBunchMap extends HashCommon<Object> implements BunchMap
{
protected TripleBunch [] values;
public HashedBunchMap()
{
super( 10 );
values = new TripleBunch[capacity];
}
@Override protected Object[] newKeyArray( int size )
{ return new Object[size]; }
/**
Clear this map: all entries are removed. The keys <i>and value</i> array
elements are set to null (so the values may be garbage-collected).
*/
@Override
public void clear()
{
size = 0;
for (int i = 0; i < capacity; i += 1) keys[i] = values[i] = null;
}
@Override
public long size()
{ return size; }
@Override
public TripleBunch get( Object key )
{
int slot = findSlot( key );
return slot < 0 ? values[~slot] : null;
}
@Override
public void put( Object key, TripleBunch value )
{
int slot = findSlot( key );
if (slot < 0)
values[~slot] = value;
else
put$(slot, key, value) ;
}
@Override
public TripleBunch getOrSet( Object key, Function<Object, TripleBunch> setter) {
int slot = findSlot( key );
if (slot < 0)
// Get.
return values[~slot] ;
// Or set value.
TripleBunch value = setter.apply(key) ;
put$(slot, key, value) ;
return value ;
}
private void put$(int slot, Object key, TripleBunch value) {
keys[slot] = key;
values[slot] = value;
size += 1;
if ( size == threshold )
grow();
}
protected void grow()
{
Object [] oldContents = keys;
TripleBunch [] oldValues = values;
final int oldCapacity = capacity;
growCapacityAndThreshold();
keys = newKeyArray( capacity );
values = new TripleBunch[capacity];
for (int i = 0; i < oldCapacity; i += 1)
{
Object key = oldContents[i];
if (key != null)
{
int j = findSlot( key );
if (j < 0)
{
throw new BrokenException( "oh dear, already have a slot for " + key + ", viz " + ~j );
}
keys[j] = key;
values[j] = oldValues[i];
}
}
}
/**
Called by HashCommon when a key is removed: remove
associated element of the <code>values</code> array.
*/
@Override protected void removeAssociatedValues( int here )
{ values[here] = null; }
/**
Called by HashCommon when a key is moved: move the
associated element of the <code>values</code> array.
*/
@Override protected void moveAssociatedValues( int here, int scan )
{ values[here] = values[scan]; }
}