Permalink
Browse files

nonblocking and() and or() impls w tests

  • Loading branch information...
1 parent bda857d commit b7ca0f20794ab9b785d9d7818230286821b51a12 d committed Apr 28, 2011
@@ -0,0 +1,43 @@
+<component name="InspectionProjectProfileManager">
+ <profile version="1.0" is_locked="false">
+ <option name="myName" value="Project Default" />
+ <option name="myLocal" value="false" />
+ <inspection_tool class="JavaDoc" enabled="false" level="WARNING" enabled_by_default="false">
+ <option name="TOP_LEVEL_CLASS_OPTIONS">
+ <value>
+ <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
+ <option name="REQUIRED_TAGS" value="" />
+ </value>
+ </option>
+ <option name="INNER_CLASS_OPTIONS">
+ <value>
+ <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
+ <option name="REQUIRED_TAGS" value="" />
+ </value>
+ </option>
+ <option name="METHOD_OPTIONS">
+ <value>
+ <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
+ <option name="REQUIRED_TAGS" value="@return@param@throws or @exception" />
+ </value>
+ </option>
+ <option name="FIELD_OPTIONS">
+ <value>
+ <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
+ <option name="REQUIRED_TAGS" value="" />
+ </value>
+ </option>
+ <option name="IGNORE_DEPRECATED" value="false" />
+ <option name="IGNORE_JAVADOC_PERIOD" value="true" />
+ <option name="IGNORE_DUPLICATED_THROWS" value="false" />
+ <option name="IGNORE_POINT_TO_ITSELF" value="false" />
+ <option name="myAdditionalJavadocTags" value="" />
+ </inspection_tool>
+ <inspection_tool class="UnusedDeclaration" enabled="false" level="WARNING" enabled_by_default="false">
+ <option name="ADD_MAINS_TO_ENTRIES" value="true" />
+ <option name="ADD_APPLET_TO_ENTRIES" value="true" />
+ <option name="ADD_SERVLET_TO_ENTRIES" value="true" />
+ <option name="ADD_NONJAVA_TO_ENTRIES" value="true" />
+ </inspection_tool>
+ </profile>
+</component>
@@ -0,0 +1,7 @@
+<component name="InspectionProjectProfileManager">
+ <settings>
+ <option name="PROJECT_PROFILE" value="Project Default" />
+ <option name="USE_PROJECT_PROFILE" value="true" />
+ <version value="1.0" />
+ </settings>
+</component>
@@ -0,0 +1,11 @@
+<component name="libraryTable">
+ <library name="test-lib">
+ <CLASSES>
+ <root url="file://$PROJECT_DIR$/test/packages" />
+ <root url="file://$PROJECT_DIR$/test/packages" />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES />
+ <jarDirectory url="file://$PROJECT_DIR$/test/packages" recursive="false" />
+ </library>
+</component>
View
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="CodeStyleSettingsManager">
+ <option name="PER_PROJECT_SETTINGS">
+ <value>
+ <ADDITIONAL_INDENT_OPTIONS fileType="java">
+ <option name="INDENT_SIZE" value="4" />
+ <option name="CONTINUATION_INDENT_SIZE" value="8" />
+ <option name="TAB_SIZE" value="4" />
+ <option name="USE_TAB_CHARACTER" value="false" />
+ <option name="SMART_TABS" value="false" />
+ <option name="LABEL_INDENT_SIZE" value="0" />
+ <option name="LABEL_INDENT_ABSOLUTE" value="false" />
+ <option name="USE_RELATIVE_INDENTS" value="false" />
+ </ADDITIONAL_INDENT_OPTIONS>
+ <ADDITIONAL_INDENT_OPTIONS fileType="js">
+ <option name="INDENT_SIZE" value="4" />
+ <option name="CONTINUATION_INDENT_SIZE" value="8" />
+ <option name="TAB_SIZE" value="4" />
+ <option name="USE_TAB_CHARACTER" value="false" />
+ <option name="SMART_TABS" value="false" />
+ <option name="LABEL_INDENT_SIZE" value="0" />
+ <option name="LABEL_INDENT_ABSOLUTE" value="false" />
+ <option name="USE_RELATIVE_INDENTS" value="false" />
+ </ADDITIONAL_INDENT_OPTIONS>
+ <ADDITIONAL_INDENT_OPTIONS fileType="scala">
+ <option name="INDENT_SIZE" value="2" />
+ <option name="CONTINUATION_INDENT_SIZE" value="2" />
+ <option name="TAB_SIZE" value="2" />
+ <option name="USE_TAB_CHARACTER" value="false" />
+ <option name="SMART_TABS" value="false" />
+ <option name="LABEL_INDENT_SIZE" value="0" />
+ <option name="LABEL_INDENT_ABSOLUTE" value="false" />
+ <option name="USE_RELATIVE_INDENTS" value="false" />
+ </ADDITIONAL_INDENT_OPTIONS>
+ <ADDITIONAL_INDENT_OPTIONS fileType="xml">
+ <option name="INDENT_SIZE" value="4" />
+ <option name="CONTINUATION_INDENT_SIZE" value="8" />
+ <option name="TAB_SIZE" value="4" />
+ <option name="USE_TAB_CHARACTER" value="false" />
+ <option name="SMART_TABS" value="false" />
+ <option name="LABEL_INDENT_SIZE" value="0" />
+ <option name="LABEL_INDENT_ABSOLUTE" value="false" />
+ <option name="USE_RELATIVE_INDENTS" value="false" />
+ </ADDITIONAL_INDENT_OPTIONS>
+ </value>
+ </option>
+ </component>
+</project>
+
@@ -0,0 +1,28 @@
+package com.boundary;
+
+/**
+ * utility for printing bit patterns
+ */
+public class BitPrint {
+ public static String fmt(long bits) {
+ StringBuilder sb = new StringBuilder();
+ long mask = 1L<<63;
+ for(int i = 1; i <= 64; i++) {
+ if((mask & bits) == mask)
+ sb.append("1");
+ else
+ sb.append("0");
+ if(i%8 == 0)
+ sb.append("|");
+ mask >>>= 1;
+ }
+ return sb.toString();
+ }
+ public static String fmt(long ... buffer) {
+ StringBuilder sb = new StringBuilder();
+ for(long bits : buffer) {
+ sb.append(fmt(bits)).append("\n");
+ }
+ return sb.toString();
+ }
+}
@@ -64,6 +64,10 @@ public NonBlockingSetInt( ) {
_nbsi = new NBSI(63, new Counter(), this); // The initial 1-word set
}
+ private NonBlockingSetInt(NonBlockingSetInt a, NonBlockingSetInt b) {
+ _nbsi = new NBSI(a._nbsi,b._nbsi,new Counter(),this);
+ }
+
/**
* Add {@code i} to the set. Uppercase {@link Integer} version of add,
* requires auto-unboxing. When possible use the {@code int} version of
@@ -133,6 +137,24 @@ public void clear ( ) {
;
}
+ /*****************************************************************
+ *
+ * bitwise comparisons optimised for NBSI
+ *
+ *****************************************************************/
+
+ public NonBlockingSetInt and(final NonBlockingSetInt op) {
+ NonBlockingSetInt res = new NonBlockingSetInt(this,op);
+ res._nbsi.and(res._nbsi,this._nbsi,op._nbsi);
+ return res;
+ }
+
+ public NonBlockingSetInt or(final NonBlockingSetInt op) {
+ NonBlockingSetInt res = new NonBlockingSetInt(this,op);
+ res._nbsi.or(res._nbsi,this._nbsi,op._nbsi);
+ return res;
+ }
+
/** Verbose printout of internal structure for debugging. */
public void print() { _nbsi.print(0); }
@@ -262,7 +284,40 @@ private NBSI( int max_elem, Counter ctr, NonBlockingSetInt nonb ) {
_nbsi64 = ((max_elem+1)>>>6) == 0 ? null : new NBSI((max_elem+1)>>>6, null, null);
_sum_bits_length = _bits.length + (_nbsi64==null ? 0 : _nbsi64._sum_bits_length);
}
-
+
+ /** built a new NBSI with buffers large enough to hold bitwise operations on the operands **/
+ private NBSI(NBSI a, NBSI b, Counter ctr, NonBlockingSetInt nonb) {
+ super();
+ _non_blocking_set_int = nonb;
+ _size = ctr;
+ _copyIdx = ctr == null ? null : new AtomicInteger();
+ _copyDone = ctr == null ? null : new AtomicInteger();
+
+ if(!has_bits(a) && !has_bits(b)) {
+ _bits = null;
+ _nbsi64 = null;
+ _sum_bits_length = 0;
+ return;
+ }
+
+ if(!has_bits(a)) {
+ _bits = new long[b._bits.length];
+ _nbsi64 = new NBSI(null,b._nbsi64,null,null);
+ } else if(!has_bits(b)) {
+ _bits = new long[a._bits.length];
+ _nbsi64 = new NBSI(null,a._nbsi64,null,null);
+ } else {
+ int bit_length = a._bits.length > b._bits.length ? a._bits.length : b._bits.length;
+ _bits = new long[bit_length];
+ _nbsi64 = new NBSI(a._nbsi64,b._nbsi64,null,null);
+ }
+ _sum_bits_length = _bits.length + _nbsi64._sum_bits_length;
+ }
+
+ private static boolean has_bits(NBSI n) {
+ return n != null && n._bits != null;
+ }
+
// Lower-case 'int' versions - no autoboxing, very fast.
// 'i' is known positive.
public boolean add( final int i ) {
@@ -338,7 +393,55 @@ public boolean contains( final int i ) {
// Yes mutable: test & return bit
return (old & mask) != 0;
}
-
+
+ /**
+ * Bitwise AND together two NBSIs, storing the result in this instance.
+ * Assumes that this instance contains ample buffer space to store the largest
+ * buffer from each NBSI in the recursive bitmap.
+ *
+ * Also assumes that this method is called during the construction process of
+ * the bitset before the instance could be leaked to multiple threads.
+ ***/
+ public boolean and(NBSI dest, NBSI a, NBSI b) {
+ // terminate recursion if one bitset is missing data
+ // since that word should be left as 0L anyway
+ if(!has_bits(a) || !has_bits(b))
+ return true;
+ for(int i = 0; i < dest._bits.length; i++) {
+ long left = a.safe_read_word(i,0L);
+ long right = b.safe_read_word(i,0L);
+ dest._bits[i] = (left & right) & Long.MAX_VALUE; // mask sign bit
+ }
+ // todo - recompute size
+ return and(dest._nbsi64,a._nbsi64,b._nbsi64);
+ }
+
+ public boolean or(NBSI dest, NBSI a, NBSI b) {
+ // terminate recursion if neiter bitset has data
+ if(!has_bits(a) && !has_bits(b))
+ return true;
+ if(has_bits(a) || has_bits(b)) {
+ for(int i = 0; i < dest._bits.length; i++) {
+ long left = a.safe_read_word(i,0);
+ long right = b.safe_read_word(i,0);
+ dest._bits[i] = (left | right) & Long.MAX_VALUE;
+ }
+ }
+ return or(dest._nbsi64,a._nbsi64,b._nbsi64);
+ }
+
+ private long safe_read_word(int i, long default_word) {
+ if(i >= _bits.length) {
+ // allow reading past the end of the buffer filling in a default word
+ return default_word;
+ }
+ long word = _bits[i];
+ if(word < 0) {
+ word = help_copy_impl(i).help_copy()._bits[i];
+ }
+ return word;
+ }
+
public int size() { return (int)_size.get(); }
// Must grow the current array to hold an element of size i
@@ -0,0 +1,13 @@
+package com.boundary;
+
+import junit.framework.TestCase;
+
+public class BitPrintTest extends TestCase {
+ public void testBitPrinting() {
+ long[] buf = new long[256];
+ for(int i = 0; i < buf.length; i++) {
+ buf[i] = i;
+ }
+ System.out.println(BitPrint.fmt(buf));
+ }
+}
Oops, something went wrong.

0 comments on commit b7ca0f2

Please sign in to comment.