Skip to content

Commit

Permalink
compute() part 2 (#13)
Browse files Browse the repository at this point in the history
* Clean up and javadoc fixes (#1)

* RD-93 lockfree pooling (#2)

* V13us without synchronized pools and NT

* ObjectPool<Node>

* V16 without synchronized pools

* V16 without synchronized pools

* V16 without synchronized pools

* V16 without synchronized pools

* V16 without synchronized pools

* V16 without synchronized pools

* 2.3.0

* 2.3.0
  • Loading branch information
improbable-til authored and tzaeschke committed Mar 19, 2019
1 parent 62cbe14 commit 5894629
Show file tree
Hide file tree
Showing 11 changed files with 1,270 additions and 27 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG
Original file line number Original file line Diff line number Diff line change
@@ -1,3 +1,10 @@
2019-03-18
==========
Release 2.3.0
- (TZ for Improbable) Fixed bug in compute()/computeIfPresent() in V13
- (TZ for Improbable) Added missing compute functions fot PhTreeF, PhTreeSolid and PhTreeSolidF
- (TZ for Improbable) Minor cleanup

2019-03-15 2019-03-15
========== ==========
Release 2.2.0 Release 2.2.0
Expand Down
120 changes: 117 additions & 3 deletions src/main/java/ch/ethz/globis/phtree/PhTreeF.java
Original file line number Original file line Diff line number Diff line change
@@ -1,12 +1,27 @@
/* /*
* Copyright 2011-2016 ETH Zurich. All Rights Reserved. * Copyright 2011-2016 ETH Zurich. All Rights Reserved.
* Copyright 2016-2018 Tilmann Zäschke. All Rights Reserved.
* Copyright 2019 Improbable. All rights reserved.
* *
* This software is the proprietary information of ETH Zurich. * This file is part of the PH-Tree project.
* Use is subject to license terms. *
* Licensed 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 ch.ethz.globis.phtree; package ch.ethz.globis.phtree;


import java.util.List; import java.util.List;
import java.util.function.BiFunction;
import java.util.function.Function;


import ch.ethz.globis.phtree.PhTree.PhExtent; import ch.ethz.globis.phtree.PhTree.PhExtent;
import ch.ethz.globis.phtree.PhTree.PhKnnQuery; import ch.ethz.globis.phtree.PhTree.PhKnnQuery;
Expand Down Expand Up @@ -494,7 +509,7 @@ public T update(double[] oldKey, double[] newKey) {
*/ */
public List<PhEntryF<T>> queryAll(double[] min, double[] max) { public List<PhEntryF<T>> queryAll(double[] min, double[] max) {
return queryAll(min, max, Integer.MAX_VALUE, null, return queryAll(min, max, Integer.MAX_VALUE, null,
e -> new PhEntryF<T>(PhMapperK.toDouble(e.getKey()), e.getValue())); e -> new PhEntryF<>(PhMapperK.toDouble(e.getKey()), e.getValue()));
} }


/** /**
Expand Down Expand Up @@ -556,5 +571,104 @@ public String toString() {
public PhTreeStats getStats() { public PhTreeStats getStats() {
return pht.getStats(); return pht.getStats();
} }


// Overrides of JDK8 Map extension methods

/**
* @see java.util.Map#getOrDefault(Object, Object)
* @param key key
* @param defaultValue default value
* @return actual value or default value
*/
public T getOrDefault(double[] key, T defaultValue) {
T t = get(key);
return t == null ? defaultValue : t;
}

/**
* @see java.util.Map#putIfAbsent(Object, Object)
* @param key key
* @param value new value
* @return previous value or null
*/
public T putIfAbsent(double[] key, T value) {
long[] lKey = new long[key.length];
pre.pre(key, lKey);
return pht.putIfAbsent(lKey, value);
}

/**
* @see java.util.Map#remove(Object, Object)
* @param key key
* @param value value
* @return {@code true} if the value was removed
*/
public boolean remove(double[] key, T value) {
long[] lKey = new long[key.length];
pre.pre(key, lKey);
return pht.remove(lKey, value);
}

/**
* @see java.util.Map#replace(Object, Object, Object)
* @param key key
* @param oldValue old value
* @param newValue new value
* @return {@code true} if the value was replaced
*/
public boolean replace(double[] key, T oldValue, T newValue) {
long[] lKey = new long[key.length];
pre.pre(key, lKey);
return pht.replace(lKey, oldValue, newValue);
}

/**
* @see java.util.Map#replace(Object, Object)
* @param key key
* @param value new value
* @return previous value or null
*/
public T replace(double[] key, T value) {
long[] lKey = new long[key.length];
pre.pre(key, lKey);
return pht.replace(lKey, value);
}

/**
* @see java.util.Map#computeIfAbsent(Object, Function)
* @param key key
* @param mappingFunction mapping function
* @return new value or null if none is associated
*/
public T computeIfAbsent(double[] key, Function<double[], ? extends T> mappingFunction) {
long[] lKey = new long[key.length];
pre.pre(key, lKey);
return pht.computeIfAbsent(lKey, longs -> mappingFunction.apply(key));
}

/**
* @see java.util.Map#computeIfPresent(Object, BiFunction)
* @param key key
* @param remappingFunction mapping function
* @return new value or null if none is associated
*/
public T computeIfPresent(double[] key, BiFunction<double[], ? super T, ? extends T> remappingFunction) {
long[] lKey = new long[key.length];
pre.pre(key, lKey);
return pht.computeIfPresent(lKey, (longs, t) -> remappingFunction.apply(key, t));
}

/**
* @see java.util.Map#compute(Object, BiFunction)
* @param key key
* @param remappingFunction mapping function
* @return new value or null if none is associated
*/
public T compute(double[] key, BiFunction<double[], ? super T, ? extends T> remappingFunction) {
long[] lKey = new long[key.length];
pre.pre(key, lKey);
return pht.compute(lKey, (longs, t) -> remappingFunction.apply(key, t));
}
} }


154 changes: 151 additions & 3 deletions src/main/java/ch/ethz/globis/phtree/PhTreeSolid.java
Original file line number Original file line Diff line number Diff line change
@@ -1,12 +1,27 @@
/* /*
* Copyright 2011-2016 ETH Zurich. All Rights Reserved. * Copyright 2011-2016 ETH Zurich. All Rights Reserved.
* Copyright 2016-2018 Tilmann Zäschke. All Rights Reserved.
* Copyright 2019 Improbable. All rights reserved.
* *
* This software is the proprietary information of ETH Zurich. * This file is part of the PH-Tree project.
* Use is subject to license terms. *
* Licensed 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 ch.ethz.globis.phtree; package ch.ethz.globis.phtree;


import java.util.Arrays; import java.util.Arrays;
import java.util.function.BiFunction;
import java.util.function.Function;


import ch.ethz.globis.phtree.PhTree.PhIterator; import ch.ethz.globis.phtree.PhTree.PhIterator;
import ch.ethz.globis.phtree.PhTree.PhQuery; import ch.ethz.globis.phtree.PhTree.PhQuery;
Expand All @@ -24,12 +39,27 @@
*/ */
public class PhTreeSolid<T> implements Iterable<T> { public class PhTreeSolid<T> implements Iterable<T> {


@FunctionalInterface
public interface SolidBiFunction<T, U, R> {

/**
* Applies this function to the given arguments.
*
* @param lower lower left corner
* @param upper upper right corner
* @param value the value
* @return the function result
*/
R apply(T lower, T upper, U value);
}

private final int dims; private final int dims;
private final PhTree<T> pht; private final PhTree<T> pht;
private final PreProcessorRange pre; private final PreProcessorRange pre;
private final long[] qMIN; private final long[] qMIN;
private final long[] qMAX; private final long[] qMAX;



/** /**
* Create a new tree with the specified number of dimensions. * Create a new tree with the specified number of dimensions.
* *
Expand Down Expand Up @@ -58,6 +88,16 @@ public PhTreeSolid(PhTree<T> tree) {
Arrays.fill(qMAX, Long.MAX_VALUE); Arrays.fill(qMAX, Long.MAX_VALUE);
} }


/**
* Create a new range tree backed by the the specified tree.
* Note that the backing tree's dimensionality must be a multiple of 2.
*
* @param tree the backing tree
*/
public static <T> PhTreeSolid<T> wrap(PhTree<T> tree) {
return new PhTreeSolid<>(tree);
}

/** /**
* Create a new tree with the specified number of dimensions. * Create a new tree with the specified number of dimensions.
* *
Expand Down Expand Up @@ -351,7 +391,7 @@ public void setValue(T value) {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if (obj == null || !(obj instanceof PhEntryS)) { if (!(obj instanceof PhEntryS)) {
return false; return false;
} }
PhEntryS<T> e = (PhEntryS<T>) obj; PhEntryS<T> e = (PhEntryS<T>) obj;
Expand Down Expand Up @@ -425,4 +465,112 @@ public PhTreeStats getStats() {
public String toStringTree() { public String toStringTree() {
return pht.toStringTree(); return pht.toStringTree();
} }

// Overrides of JDK8 Map extension methods

/**
* @see java.util.Map#getOrDefault(Object, Object)
* @param lower lower left corner
* @param upper upper right corner
* @param defaultValue default value
* @return actual value or default value
*/
public T getOrDefault(long[] lower, long[] upper, T defaultValue) {
T t = get(lower, upper);
return t == null ? defaultValue : t;
}

/**
* @see java.util.Map#putIfAbsent(Object, Object)
* @param lower lower left corner
* @param upper upper right corner
* @param value new value
* @return previous value or null
*/
public T putIfAbsent(long[] lower, long[] upper, T value) {
long[] key = new long[lower.length*2];
pre.pre(lower, upper, key);
return pht.putIfAbsent(key, value);
}

/**
* @see java.util.Map#remove(Object, Object)
* @param lower lower left corner
* @param upper upper right corner
* @param value value
* @return {@code true} if the value was removed
*/
public boolean remove(long[] lower, long[] upper, T value) {
long[] key = new long[lower.length*2];
pre.pre(lower, upper, key);
return pht.remove(key, value);
}

/**
* @see java.util.Map#replace(Object, Object, Object)
* @param lower lower left corner
* @param upper upper right corner
* @param oldValue old value
* @param newValue new value
* @return {@code true} if the value was replaced
*/
public boolean replace(long[] lower, long[] upper, T oldValue, T newValue) {
long[] key = new long[lower.length*2];
pre.pre(lower, upper, key);
return pht.replace(key, oldValue, newValue);
}

/**
* @see java.util.Map#replace(Object, Object)
* @param lower lower left corner
* @param upper upper right corner
* @param value new value
* @return previous value or null
*/
public T replace(long[] lower, long[] upper, T value) {
long[] key = new long[lower.length*2];
pre.pre(lower, upper, key);
return pht.replace(key, value);
}

/**
* @see java.util.Map#computeIfAbsent(Object, Function)
* @param lower lower left corner
* @param upper upper right corner
* @param mappingFunction mapping function
* @return new value or null if none is associated
*/
public T computeIfAbsent(long[] lower, long[] upper, BiFunction<long[], long[], ? extends T> mappingFunction) {
long[] key = new long[lower.length*2];
pre.pre(lower, upper, key);
return pht.computeIfAbsent(key, (longs) -> mappingFunction.apply(lower, upper));
}

/**
* @see java.util.Map#computeIfPresent(Object, BiFunction)
* @param lower lower left corner
* @param upper upper right corner
* @param remappingFunction mapping function
* @return new value or null if none is associated
*/
public T computeIfPresent(long[] lower, long[] upper,
SolidBiFunction<long[], ? super T, ? extends T> remappingFunction) {
long[] key = new long[lower.length*2];
pre.pre(lower, upper, key);
return pht.computeIfPresent(key, (longs, value) -> remappingFunction.apply(lower, upper, value));
}

/**
* @see java.util.Map#compute(Object, BiFunction)
* @param lower lower left corner
* @param upper upper right corner
* @param remappingFunction mapping function
* @return new value or null if none is associated
*/
public T compute(long[] lower, long[] upper, SolidBiFunction<long[], ? super T, ? extends T> remappingFunction) {
long[] key = new long[lower.length*2];
pre.pre(lower, upper, key);
return pht.compute(key, (longs, value) -> remappingFunction.apply(lower, upper, value));
}

} }
Loading

0 comments on commit 5894629

Please sign in to comment.