Skip to content

Commit

Permalink
Javadoc changes for thread-safe variant
Browse files Browse the repository at this point in the history
  • Loading branch information
gstamatelat committed Nov 28, 2019
1 parent 7300929 commit d300ef4
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 18 deletions.
Original file line number Diff line number Diff line change
@@ -1,18 +1,13 @@
package gr.james.sampling;

import java.util.AbstractList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import java.util.RandomAccess;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReferenceArray;

/**
* This class provides a skeletal implementation of the {@link RandomSampling} interface to minimize the effort required
* to implement that interface.
* This class provides a skeletal implementation of the thread-safe variant of the {@link RandomSampling} interface to
* minimize the effort required to implement that interface.
*
* @param <T> the item type
* @author Giorgos Stamatelatos
Expand Down Expand Up @@ -79,28 +74,28 @@ public final boolean feed(T item) {


// attempt to add to samples while we don't have a full count yet, until successful or array is full
for(int samplesInArray = samplesCount.get(); samplesInArray < sampleSize;) {
for (int samplesInArray = samplesCount.get(); samplesInArray < sampleSize; ) {
boolean arrayWasModified = sample.compareAndSet(samplesInArray, null, item);
if(!arrayWasModified)
if (!arrayWasModified)
continue;
samplesInArray = samplesCount.incrementAndGet();
assert samplesInArray == Math.min(sampleSize(), streamSize);
return true;
}

// try to either decrement the skip count or calculate a new skip count value, until either succeeds
while(true) {
while (true) {
long currentSkipValue = skip.get();
if(currentSkipValue > 0) {
if (currentSkipValue > 0) {
boolean decrementSuccess = skip.compareAndSet(currentSkipValue, currentSkipValue - 1);
if(decrementSuccess) {
if (decrementSuccess) {
return false;
}
} else {
assert currentSkipValue == 0;
long nextSkipValue = skipLength(streamSize, sampleSize, random);
boolean skipCountUpdated = skip.compareAndSet(currentSkipValue, nextSkipValue);
if(skipCountUpdated) {
if (skipCountUpdated) {
sample.set(random.nextInt(sampleSize), item);
assert nextSkipValue >= 0;
return true;
Expand Down
8 changes: 5 additions & 3 deletions src/main/java/gr/james/sampling/LiLSamplingThreadSafe.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
* This property allows these algorithms to perform better by efficiently calculating the number of items that need to
* be skipped, while making fewer calls to the RNG.
* <p>
* This is the thread-safe implementation of {@link LiLSampling}.
* <p>
* This implementation throws {@link StreamOverflowException} if more than {@link Long#MAX_VALUE} items are feeded.
* <p>
* The space complexity of this class is {@code O(k)}, where {@code k} is the sample size.
Expand All @@ -28,9 +30,9 @@ public class LiLSamplingThreadSafe<T> extends AbstractThreadSafeRandomSampling<T
private AtomicLong W;

/**
* Construct a new instance of {@link LiLSamplingThreadSafe} using the specified sample size and RNG. The implementation
* assumes that {@code random} conforms to the contract of {@link Random} and will perform no checks to ensure that.
* If this contract is violated, the behavior is undefined.
* Construct a new instance of {@link LiLSamplingThreadSafe} using the specified sample size and RNG. The
* implementation assumes that {@code random} conforms to the contract of {@link Random} and will perform no checks
* to ensure that. If this contract is violated, the behavior is undefined.
*
* @param sampleSize the sample size
* @param random the RNG to use
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@
/**
* Marker interface.
*/
public interface ThreadSafeRandomSampling {}
public interface ThreadSafeRandomSampling {
}
7 changes: 7 additions & 0 deletions src/main/java/gr/james/sampling/package-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
* <th>Space</th>
* <th>Precision</th>
* <th>Weights</th>
* <th>Thread-Safe Version</th>
* </tr>
* </thead>
* <tbody>
Expand All @@ -67,41 +68,47 @@
* <td>{@code O(k)}</td>
* <td>D</td>
* <td>-</td>
* <td>-</td>
* </tr>
* <tr>
* <td>{@link gr.james.sampling.VitterXSampling}</td>
* <td>Algorithm X by Vitter [3]</td>
* <td>{@code O(k)}</td>
* <td>D</td>
* <td>-</td>
* <td>-</td>
* </tr>
* <tr>
* <td>{@link gr.james.sampling.VitterZSampling}</td>
* <td>Algorithm Z by Vitter [3]</td>
* <td>{@code O(k)}</td>
* <td>D</td>
* <td>-</td>
* <td>-</td>
* </tr>
* <tr>
* <td>{@link gr.james.sampling.LiLSampling}</td>
* <td>Algorithm L by Li [4]</td>
* <td>{@code O(k)}</td>
* <td>D</td>
* <td>-</td>
* <td>{@link gr.james.sampling.LiLSamplingThreadSafe}</td>
* </tr>
* <tr>
* <td>{@link gr.james.sampling.ChaoSampling}</td>
* <td>Algorithm by Chao [5][6]</td>
* <td>{@code O(k)}</td>
* <td>D</td>
* <td>P (0, +&infin;)</td>
* <td>-</td>
* </tr>
* <tr>
* <td>{@link gr.james.sampling.EfraimidisSampling}</td>
* <td>Algorithm A-Res by Efraimidis [7]</td>
* <td>{@code O(k)}</td>
* <td>ND</td>
* <td>W (0, +&infin;)</td>
* <td>-</td>
* </tr>
* </tbody>
* </table>
Expand Down

0 comments on commit d300ef4

Please sign in to comment.