1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415
|
package ukmer;
import java.util.ArrayList;
import java.util.Arrays;
import fileIO.TextStreamWriter;
import shared.Tools;
import structures.ByteBuilder;
import structures.SuperLongList;
/**
* @author Brian Bushnell
* @date Oct 22, 2013
*
*/
public abstract class KmerNodeU extends AbstractKmerTableU {
/*--------------------------------------------------------------*/
/*---------------- Initialization ----------------*/
/*--------------------------------------------------------------*/
protected KmerNodeU(long[] pivot_){
pivot=pivot_.clone();
}
public abstract KmerNodeU makeNode(long[] pivot_, int value_);
public abstract KmerNodeU makeNode(long[] pivot_, int[] values_);
/*--------------------------------------------------------------*/
/*---------------- Public Methods ----------------*/
/*--------------------------------------------------------------*/
@Override
public final int increment(Kmer kmer){return increment(kmer.key());}
public final int increment(long[] kmer){
final int cmp=compare(kmer, pivot);
if(cmp<0){
if(left==null){left=makeNode(kmer, 1); return 1;}
return left.increment(kmer);
}else if(cmp>0){
if(right==null){right=makeNode(kmer, 1); return 1;}
return right.increment(kmer);
}else{
if(value()<Integer.MAX_VALUE){set(value()+1);}
return value();
}
}
@Override
public final int incrementAndReturnNumCreated(Kmer kmer){return incrementAndReturnNumCreated(kmer.key());}
public final int incrementAndReturnNumCreated(long[] kmer) {
int x=increment(kmer);
return x==1 ? 1 : 0;
}
/** Returns number of nodes added */
public final int set(long[] kmer, int value){
if(verbose){System.err.println("Set0: kmer="+Arrays.toString(kmer)+", v="+value+", old="+Arrays.toString(values(new int[1])));}
if(verbose){System.err.println("A");}
final int cmp=compare(kmer, pivot);
if(cmp<0){
if(verbose){System.err.println("B");}
if(left==null){left=makeNode(kmer, value); return 1;}
if(verbose){System.err.println("C");}
return left.set(kmer, value);
}else if(cmp>0){
if(verbose){System.err.println("D");}
if(right==null){right=makeNode(kmer, value); return 1;}
if(verbose){System.err.println("E");}
return right.set(kmer, value);
}else{
if(verbose){System.err.println("F");}
set(value);
}
if(verbose){System.err.println("G");}
return 0;
}
/** Returns number of nodes added */
public final int setIfNotPresent(long[] kmer, int value){
if(verbose){System.err.println("setIfNotPresent0: kmer="+kmer+", v="+value+", old="+Arrays.toString(values(new int[0])));}
final int cmp=compare(kmer, pivot);
if(cmp<0){
if(left==null){left=makeNode(kmer, value); return 1;}
return left.setIfNotPresent(kmer, value);
}else if(cmp>0){
if(right==null){right=makeNode(kmer, value); return 1;}
return right.setIfNotPresent(kmer, value);
}
return 0;
}
public final int getValue(long[] kmer){
KmerNodeU n=get(kmer);
return n==null ? -1 : n.value();
}
public final int[] getValues(long[] kmer, int[] singleton){
KmerNodeU n=get(kmer);
return n==null ? null : n.values(singleton);
}
public final boolean contains(long[] kmer){
KmerNodeU node=get(kmer);
return node!=null;
}
/*--------------------------------------------------------------*/
/*---------------- Nonpublic Methods ----------------*/
/*--------------------------------------------------------------*/
public KmerNodeU left(){return left;}
public KmerNodeU right(){return right;}
public long[] pivot(){return pivot;}
public int owner(){return owner;}
public Kmer fillKmer(Kmer x){
assert(pivot!=null);
long[] key=x.array1();
for(int i=0; i<pivot.length; i++){
key[i]=pivot[i];
}
x.fillArray2();
return x;
}
public int count(){return value();}
protected abstract int value();
protected abstract int[] values(int[] singleton);
/** Returns new value */
public abstract int set(int value_);
protected abstract int set(int[] values_);
@Override
final KmerNodeU get(final long[] kmer){
// if(kmer<pivot){
// return left==null ? null : left.get(kmer);
// }else if(kmer>pivot){
// return right==null ? null : right.get(kmer);
// }else{
// return this;
// }
KmerNodeU n=this;
int cmp=compare(kmer, n.pivot);
while(cmp!=0){
n=(cmp<0 ? n.left : n.right);
cmp=(n==null ? 0 : compare(kmer, n.pivot));
}
return n;
}
final KmerNodeU getNodeOrParent(long[] kmer){
final int cmp=compare(kmer, pivot);
if(cmp==0){return this;}
if(cmp<0){return left==null ? this : left.getNodeOrParent(kmer);}
return right==null ? this : right.getNodeOrParent(kmer);
}
final boolean insert(KmerNodeU n){
assert(pivot!=null);
final int cmp=compare(n.pivot, pivot);
if(cmp<0){
if(left==null){left=n; return true;}
return left.insert(n);
}else if(cmp>0){
if(right==null){right=n; return true;}
return right.insert(n);
}else{
return false;
}
}
final void traversePrefix(ArrayList<KmerNodeU> list){
if(left!=null){left.traversePrefix(list);}
list.add(this);
if(right!=null){right.traversePrefix(list);}
}
final void traverseInfix(ArrayList<KmerNodeU> list){
list.add(this);
if(left!=null){left.traverseInfix(list);}
if(right!=null){right.traverseInfix(list);}
}
/*--------------------------------------------------------------*/
/*---------------- Private Methods ----------------*/
/*--------------------------------------------------------------*/
/*--------------------------------------------------------------*/
/*---------------- Resizing and Rebalancing ----------------*/
/*--------------------------------------------------------------*/
@Override
public final long size() {
if(value()<1){return 0;}
long size=1;
if(left!=null){size+=left.size();}
if(right!=null){size+=right.size();}
return size;
}
final KmerNodeU rebalance(ArrayList<KmerNodeU> list){
assert(list.isEmpty());
traversePrefix(list);
KmerNodeU n=this;
if(list.size()>2){
n=rebalance(list, 0, list.size()-1);
}
list.clear();
return n;
}
private static final KmerNodeU rebalance(ArrayList<KmerNodeU> list, int a, int b){
final int size=b-a+1;
final int middle=a+size/2;
final KmerNodeU n=list.get(middle);
if(size<4){
if(size==1){
n.left=n.right=null;
}else if(size==2){
KmerNodeU n1=list.get(a);
n.left=n1;
n.right=null;
n1.left=n1.right=null;
}else{
assert(size==3);
KmerNodeU n1=list.get(a), n2=list.get(b);
n.left=n1;
n.right=n2;
n1.left=n1.right=null;
n2.left=n2.right=null;
}
}else{
n.left=rebalance(list, a, middle-1);
n.right=rebalance(list, middle+1, b);
}
return n;
}
@Override
public long regenerate(final int limit){
throw new RuntimeException("Not supported.");
}
/*--------------------------------------------------------------*/
/*---------------- Info Dumping ----------------*/
/*--------------------------------------------------------------*/
@Override
public final boolean dumpKmersAsText(TextStreamWriter tsw, int k, int mincount, int maxcount) {
tsw.print(dumpKmersAsText(new StringBuilder(32), k, mincount, maxcount));
return true;
}
protected abstract StringBuilder dumpKmersAsText(StringBuilder sb, int k, int mincount, int maxcount);
protected abstract ByteBuilder dumpKmersAsText(ByteBuilder bb, int k, int mincount, int maxcount);
@Override
public final void fillHistogram(long[] ca, int max){
final int value=value();
if(value<1){return;}
ca[Tools.min(value, max)]++;
if(left!=null){left.fillHistogram(ca, max);}
if(right!=null){right.fillHistogram(ca, max);}
}
@Override
public final void fillHistogram(SuperLongList sll){
final int value=value();
if(value<1){return;}
sll.add(value);
if(left!=null){left.fillHistogram(sll);}
if(right!=null){right.fillHistogram(sll);}
}
@Override
public final void countGC(long[] gcCounts, int max){
final int value=value();
if(value<1){return;}
int index=Tools.min(value, max);
for(long x : pivot){
gcCounts[index]+=gc(x);
}
if(left!=null){left.countGC(gcCounts, max);}
if(right!=null){right.countGC(gcCounts, max);}
}
@Override
public String toString(){return Arrays.toString(pivot);}
abstract boolean TWOD();
abstract int numValues();
/*--------------------------------------------------------------*/
/*---------------- Ownership ----------------*/
/*--------------------------------------------------------------*/
@Override
public final void initializeOwnership(){
owner=-1;
if(left!=null){left.initializeOwnership();}
if(right!=null){right.initializeOwnership();}
}
@Override
public final void clearOwnership(){initializeOwnership();}
public final int setOwner(final long[] kmer, final int newOwner){
KmerNodeU n=get(kmer);
assert(n!=null);
if(n.owner<=newOwner){
synchronized(n){
if(n.owner<newOwner){
n.owner=newOwner;
}
}
}
return n.owner;
}
public final boolean clearOwner(final long[] kmer, final int owner){
KmerNodeU n=get(kmer);
assert(n!=null);
synchronized(n){
if(n.owner==owner){
n.owner=-1;
return true;
}
}
return false;
}
public final int getOwner(final long[] kmer){
KmerNodeU n=get(kmer);
assert(n!=null);
return n.owner;
}
/*--------------------------------------------------------------*/
/*---------------- Recall Methods ----------------*/
/*--------------------------------------------------------------*/
abstract int set(long[] kmer, int[] vals);
@Override
public int set(Kmer kmer, int value) {
return set(kmer.key(), value);
}
@Override
public int set(Kmer kmer, int[] vals) {
return set(kmer.key(), vals);
}
@Override
public int setIfNotPresent(Kmer kmer, int value) {
return setIfNotPresent(kmer.key(), value);
}
@Override
public int getValue(Kmer kmer) {
return getValue(kmer.key());
}
@Override
public int[] getValues(Kmer kmer, int[] singleton) {
return getValues(kmer.key(), singleton);
}
@Override
public boolean contains(Kmer kmer) {
return contains(kmer.key());
}
@Override
public int getValue(long[] key, long xor) {
return getValue(key);
}
@Override
public int setOwner(Kmer kmer, int newOwner) {
return setOwner(kmer.key(), newOwner);
}
@Override
public boolean clearOwner(Kmer kmer, int owner) {
return clearOwner(kmer.key(), owner);
}
@Override
public int getOwner(Kmer kmer) {
return getOwner(kmer.key());
}
/*--------------------------------------------------------------*/
/*---------------- Invalid Methods ----------------*/
/*--------------------------------------------------------------*/
/*--------------------------------------------------------------*/
/*---------------- Fields ----------------*/
/*--------------------------------------------------------------*/
final long[] pivot;
int owner=-1;
KmerNodeU left, right;
}
|