1 6 7 package com.hp.hpl.jena.db.impl; 8 9 import java.util.ArrayList ; 10 import java.util.Iterator ; 11 import java.util.List ; 12 13 import com.hp.hpl.jena.db.GraphRDB; 14 import com.hp.hpl.jena.graph.*; 15 import com.hp.hpl.jena.util.iterator.*; 16 import com.hp.hpl.jena.shared.*; 17 import com.hp.hpl.jena.vocabulary.RDF; 18 27 28 public class SpecializedGraphReifier_RDB 29 extends SpecializedGraphBase 30 implements SpecializedGraphReifier { 31 32 35 public PSet_ReifStore_RDB m_pset; 36 37 40 public DBPropLSet m_dbPropLSet; 41 42 45 public IDBID my_GID = null; 46 47 private ReifCacheMap m_reifCache; 49 50 public PSet_ReifStore_RDB m_reif; 51 52 54 58 SpecializedGraphReifier_RDB(DBPropLSet lProp, IPSet pSet, Integer dbGraphID) { 59 m_pset = (PSet_ReifStore_RDB) pSet; 60 m_dbPropLSet = lProp; 61 my_GID = new DBIDInt(dbGraphID); 62 m_reifCache = new ReifCacheMap(1); 63 m_reif = (PSet_ReifStore_RDB) m_pset; 64 } 65 66 72 public SpecializedGraphReifier_RDB(IPSet pSet, Integer dbGraphID) { 73 m_pset = (PSet_ReifStore_RDB) pSet; 74 my_GID = new DBIDInt(dbGraphID); 75 m_reifCache = new ReifCacheMap(1); 76 m_reif = (PSet_ReifStore_RDB) m_pset; 77 } 78 79 82 public void add(Node n, Triple t, CompletionFlag complete) throws CannotReifyException { 83 StmtMask same = new StmtMask(); 84 StmtMask diff = new StmtMask(); 85 ReifCache rs = m_reifCache.load(n, t, same, diff); 86 if (rs == null) { 87 m_reif.storeReifStmt(n, t, my_GID); 88 } else { 89 90 if ( diff.hasNada() ) { 91 boolean didUpdate = false; 92 93 if ( !same.hasSubj() ) { 94 Triple st = Triple.create(n,RDF.Nodes.subject,t.getSubject()); 95 m_reif.updateFrag(n, st, new StmtMask(st), my_GID); 96 didUpdate = true; 97 } 98 if ( !same.hasPred() ) { 99 Triple pt = Triple.create(n,RDF.Nodes.predicate,t.getPredicate()); 100 m_reif.updateFrag(n, pt, new StmtMask(pt), my_GID); 101 didUpdate = true; 102 } 103 if ( !same.hasObj() ) { 104 Triple ot = Triple.create(n,RDF.Nodes.object,t.getObject()); 105 m_reif.updateFrag(n, ot, new StmtMask(ot), my_GID); 106 didUpdate = true; 107 } 108 if ( !rs.mask.hasType() ) { 109 Triple tt = Triple.create(n,RDF.Nodes.type,RDF.Nodes.Statement); 110 m_reif.updateFrag(n, tt, new StmtMask(tt), my_GID); 111 didUpdate = true; 112 } 113 if ( didUpdate ) 114 fragCompact(n); 115 m_reifCache.flushAll(); 116 } else { 117 118 if ( rs.mask.isStmt() ) 119 throw new AlreadyReifiedException(n); 120 else 121 throw new CannotReifyException(n); 122 } 123 } 124 complete.setDone(); 125 } 126 127 130 public void delete(Node n, Triple t, CompletionFlag complete) { 131 m_reifCache.flushAll(); 132 m_reif.deleteReifStmt( n, t, my_GID); 133 complete.setDone(); 134 } 135 136 139 public boolean contains(Node n, Triple t, CompletionFlag complete) { 140 if (true) 141 throw new JenaException("SpecializedGraphReifier.contains called"); 142 return false; 143 } 144 145 148 public ExtendedIterator findReifiedNodes(Triple t, CompletionFlag complete) { 149 complete.setDone(); 150 return m_reif.findReifStmtURIByTriple(t, my_GID); 151 } 152 153 156 public Triple findReifiedTriple(Node n, CompletionFlag complete) { 157 ResultSetReifIterator it = m_reif.findReifStmt(n, true, my_GID, false); 158 Triple res = null; 159 if ( it.hasNext() ) { 160 res = (Triple) it.next(); 161 } 162 complete.setDone(); 163 return res; 164 } 165 166 186 public ExtendedIterator findReifiedTriples(Node n, CompletionFlag complete) { 187 complete.setDone(); 188 return m_reif.findReifStmt(n, false, my_GID, true); 189 } 190 191 209 public void add( Graph g, CompletionFlag complete ) { 210 throw new AddDeniedException( "sorry, not implemented" ); 211 } 212 213 216 public void add(Triple frag, CompletionFlag complete) throws AlreadyReifiedException { 217 StmtMask fragMask = new StmtMask(frag); 218 if (fragMask.hasNada()) 219 return; 220 221 boolean fragHasType = fragMask.hasType(); 222 Node stmtURI = frag.getSubject(); 223 ReifCache cachedFrag = m_reifCache.load(stmtURI); 224 if (cachedFrag == null) { 225 m_reif.storeFrag(stmtURI, frag, fragMask, my_GID); 227 complete.setDone(); 228 229 } else { 230 StmtMask cachedMask = cachedFrag.getStmtMask(); 231 if (cachedMask.hasIntersect(fragMask)) { 232 boolean dup = fragHasType && cachedMask.hasType(); 234 if (dup == false) { 235 ExtendedIterator it = m_reif.findFrag (stmtURI, frag, fragMask, my_GID); 237 dup = it.hasNext(); 238 if ( dup == false ) { 239 if ( cachedMask.isStmt()) 240 throw new AlreadyReifiedException(frag.getSubject()); 241 m_reif.storeFrag(stmtURI, frag, fragMask, my_GID); 243 m_reifCache.flush(cachedFrag); 244 } 245 } 246 } else { 247 if (cachedFrag.canMerge(fragMask)) { 249 if ( cachedFrag.canUpdate(fragMask) ) { 250 m_reif.updateFrag(stmtURI, frag, fragMask, my_GID); 251 cachedFrag.update(fragMask); 252 } else 253 fragCompact(stmtURI); 254 } else { 255 m_reif.storeFrag(stmtURI, frag, fragMask, my_GID); 257 } 258 } 259 } 260 complete.setDone(); 261 } 262 263 266 public void delete(Triple frag, CompletionFlag complete) { 267 StmtMask fragMask = new StmtMask(frag); 268 if (fragMask.hasNada()) 269 return; 270 271 Node stmtURI = frag.getSubject(); 272 273 ResultSetReifIterator it = m_reif.findFrag(stmtURI, frag, fragMask, my_GID); 274 if ( it.hasNext() ) { 275 if ( it.getFragCount() == 1 ) { 276 277 m_reif.deleteFrag(frag, fragMask, my_GID); 278 it.close(); 279 } else { 280 281 m_reif.nullifyFrag(stmtURI, fragMask, my_GID); 282 283 284 it.close(); 285 fragCompact(stmtURI); 286 } 287 ReifCache cachedFrag = m_reifCache.lookup(stmtURI); 289 if ( cachedFrag != null ) m_reifCache.flush(cachedFrag); 290 } 291 complete.setDone(); 292 } 293 294 295 303 protected void fragCompact ( Node stmtURI ) { 304 ResultSetReifIterator itHasType; 305 Triple t; 306 307 itHasType = m_reif.findReifStmt(stmtURI,true,my_GID, false); 308 if ( itHasType.hasNext() ) { 309 310 t = (Triple) itHasType.next(); 311 if ( itHasType.hasNext() ) 312 throw new JenaException("Multiple HasType fragments for URI"); 313 StmtMask htMask = new StmtMask(t); 314 itHasType.close(); 315 316 ResultSetReifIterator itFrag = m_reif.findReifStmt(stmtURI,false,my_GID, false); 318 StmtMask upMask = new StmtMask(); 319 while ( itFrag.hasNext() ) { 320 t = (Triple) itFrag.next(); 321 if ( itFrag.getHasType() ) continue; 322 StmtMask fm = new StmtMask(rowToFrag(stmtURI, t)); 323 if ( htMask.hasIntersect(fm) ) 324 break; m_reif.updateFrag(stmtURI, t, fm, my_GID); 327 htMask.setMerge(fm); 328 m_reif.deleteFrag(t, fm, my_GID); 329 } 330 } 331 } 332 333 protected Triple rowToFrag ( Node stmtURI, Triple row ) 334 { 335 Node pred = null; 336 Node obj = null; 337 int valCnt = 0; 338 339 if ( row.getSubject() != null ) { 340 obj = row.getSubject(); 341 pred = RDF.Nodes.subject; 342 valCnt++; 343 } 344 if ( row.getPredicate() != null ) { 345 obj = row.getPredicate(); 346 pred = RDF.Nodes.predicate; 347 valCnt++; 348 } 349 if ( row.getObject() != null ) { 350 obj = row.getObject(); 351 pred = RDF.Nodes.object; 352 valCnt++; 353 } 354 if ( valCnt != 1 ) 355 throw new JenaException("Partially reified row must have exactly one value"); 356 357 return Triple.create(stmtURI, pred, obj); 358 } 359 360 363 public void add(List triples, CompletionFlag complete) { 364 ArrayList remainingTriples = new ArrayList (); 365 for( int i=0; i< triples.size(); i++) { 366 CompletionFlag partialResult = newComplete(); 367 add( (Triple)triples.get(i), partialResult); 368 if( !partialResult.isDone()) 369 remainingTriples.add(triples.get(i)); 370 } 371 triples.clear(); 372 if( remainingTriples.isEmpty()) 373 complete.setDone(); 374 else 375 triples.addAll(remainingTriples); 376 } 377 378 381 public void delete(List triples, CompletionFlag complete) { 382 boolean result = true; 383 Iterator it = triples.iterator(); 384 while(it.hasNext()) { 385 CompletionFlag partialResult = newComplete(); 386 delete( (Triple)it.next(), partialResult); 387 result = result && partialResult.isDone(); 388 } 389 if( result ) 390 complete.setDone(); 391 } 392 395 public int tripleCount() { 396 ExtendedIterator it = find( null, null, null, newComplete() ); 398 int count = 0; 399 while (it.hasNext()) { 400 it.next(); count++; 401 } 402 it.close(); 403 return count; 404 } 405 406 409 public ExtendedIterator find(TripleMatch t, CompletionFlag complete) { 410 411 ResultSetReifIterator it = m_reif.findReifTripleMatch(t, my_GID); 415 return it; 416 } 417 418 425 public boolean contains(Triple t, CompletionFlag complete) { 426 ExtendedIterator it = find( t, complete ); 428 try { return it.hasNext(); } finally { it.close(); } 429 } 430 431 434 public void close() { 435 m_reif.close(); 436 } 437 438 441 public void clear() { 442 m_reif.removeStatementsFromDB(my_GID); 443 } 444 445 public class ReifCacheMap { 446 protected int cacheSize = 1; 447 protected ReifCache[] cache; 448 protected boolean[] inUse; 449 450 ReifCacheMap(int size) { 451 int i; 452 inUse = new boolean[size]; 453 cache = new ReifCache[size]; 454 for (i = 0; i < size; i++) 455 inUse[i] = false; 456 } 457 458 ReifCache lookup(Node stmtURI) { 459 int i; 460 for (i = 0; i < cache.length; i++) { 461 if (inUse[i] && (cache[i].getStmtURI().equals(stmtURI))) 462 return cache[i]; 463 } 464 return null; 465 } 466 467 public void flushAll() { 468 int i; 469 for (i = 0; i < cache.length; i++) 470 inUse[i] = false; 471 } 472 473 public void flush(ReifCache entry) { 474 flushAll(); } 476 477 public ReifCache load(Node stmtURI) { 478 ReifCache entry = lookup(stmtURI); 479 if (entry != null) 480 return entry; 481 return load(stmtURI, null, null, null); 482 } 483 484 485 public ReifCache load(Node stmtURI, Triple s, StmtMask sm, StmtMask dm ) { 486 flushAll(); 487 StmtMask m = new StmtMask(); 488 Triple t; 489 boolean hasSubj, hasPred, hasObj, hasType; 490 boolean checkSame = sm != null; 491 int cnt = 0; 492 ResultSetReifIterator it = m_reif.findReifStmt(stmtURI,false,my_GID, false); 493 while (it.hasNext()) { 494 cnt++; 495 Triple db = (Triple) it.next(); 496 StmtMask n = new StmtMask(); 497 hasSubj = !db.getSubject().equals(Node.NULL); 498 if ( hasSubj && checkSame ) 499 if ( db.getSubject().equals(s.getSubject()) ) 500 sm.setHasSubj(); 501 else 502 dm.setHasSubj(); 503 hasPred = !db.getPredicate().equals(Node.NULL); 504 if ( hasPred && checkSame ) 505 if ( db.getPredicate().equals(s.getPredicate()) ) 506 sm.setHasPred(); 507 else 508 dm.setHasPred(); 509 hasObj = !db.getObject().equals(Node.NULL); 510 if ( hasObj && checkSame ) 511 if ( db.getObject().equals(s.getObject()) ) 512 sm.setHasObj(); 513 else 514 dm.setHasObj(); 515 516 hasType = it.getHasType(); 517 518 n.setMask( hasSubj, hasPred, hasObj, hasType ); 519 if ( n.hasNada() ) throw new JenaException("Fragment has no data"); 520 m.setMerge(n); 521 } 522 if ( cnt == 0 ) 523 return null; 525 if (m.hasSPOT() && (cnt == 1)) 526 m.setIsStmt(); 527 528 inUse[0] = true; 529 cache[0] = new ReifCache(stmtURI, m, cnt); 530 return cache[0]; 531 } 532 533 } 534 535 class ReifCache { 536 537 protected Node stmtURI; 538 protected StmtMask mask; 539 protected int tripleCnt; 540 541 ReifCache( Node s, StmtMask m, int cnt ) 542 { stmtURI = s; mask = m; tripleCnt = cnt; } 543 544 public StmtMask getStmtMask() { return mask; } 545 public int getCnt() { return tripleCnt; } 546 public Node getStmtURI() { return stmtURI; } 547 public void setMask ( StmtMask m ) { mask = m; } 548 public void setCnt ( int cnt ) { tripleCnt = cnt; } 549 public void incCnt ( int cnt ) { tripleCnt++; } 550 public void decCnt ( int cnt ) { tripleCnt--; } 551 public boolean canMerge ( StmtMask fragMask ) { 552 return (!mask.hasIntersect(fragMask)); } 553 public boolean canUpdate ( StmtMask fragMask ) { 554 return ( canMerge(fragMask) && (tripleCnt == 1)); } 555 public void update ( StmtMask fragMask ) { 556 mask.setMerge(fragMask); 557 if ( isStmt() ) { mask.setIsStmt(); } 558 } 559 private boolean isStmt() { 560 return mask.hasSPOT() && (tripleCnt == 1); 561 } 562 563 } 564 565 static boolean isReifProp ( Node_URI p ) { 566 return p.equals(RDF.Nodes.subject) || 567 p.equals(RDF.Nodes.predicate)|| 568 p.equals(RDF.Nodes.object) || 569 p.equals(RDF.Nodes.type); 570 } 571 572 class StmtMask { 573 574 protected int mask; 575 576 public static final int HasSubj = 1; 577 public static final int HasPred = 2; 578 public static final int HasObj = 4; 579 public static final int HasType = 8; 580 public static final int HasSPOT = 15; 581 public static final int IsStmt = 16; 582 public static final int HasNada = 0; 583 584 public boolean hasSubj () { return (mask & HasSubj) == HasSubj; } 585 public boolean hasPred () { return (mask & HasPred) == HasPred; } 586 public boolean hasObj () { return (mask & HasObj) == HasObj; } 587 public boolean hasType () { return (mask & HasType) == HasType; } 588 public boolean hasSPOT () { return (mask & HasSPOT) == HasSPOT; } 589 public boolean isStmt () { return (mask & IsStmt) == IsStmt; } 590 public boolean hasNada () { return mask == HasNada; } 591 public boolean hasOneBit () { return ( (mask == HasSubj) || 592 (mask == HasPred) || (mask == HasObj) || ( mask == HasType) ); 593 } 594 595 599 StmtMask ( Triple t ) { 600 mask = HasNada; 601 Node p = t.getPredicate(); 602 if ( p != null ) { 603 if ( p.equals(RDF.Nodes.subject) ) mask = HasSubj; 604 else if ( p.equals(RDF.Nodes.predicate) ) mask = HasPred; 605 else if ( p.equals(RDF.Nodes.object) ) mask = HasObj; 606 else if ( p.equals(RDF.Nodes.type) ) { 607 Node o = t.getObject(); 608 if ( o.equals(RDF.Nodes.Statement) ) mask = HasType; 609 } 610 } 611 } 612 613 StmtMask () { mask = HasNada; } 614 615 public void setMerge ( StmtMask m ) { 616 mask |= m.mask; 617 } 618 619 public void setHasType () { 620 mask |= HasType; 621 } 622 623 public void setMask ( boolean hasSubj, boolean hasProp, boolean hasObj, boolean hasType ) { 624 if ( hasSubj ) mask |= HasSubj; 625 if ( hasProp) mask |= HasPred; 626 if ( hasObj) mask |= HasObj; 627 if ( hasType ) mask |= HasType; 628 } 629 630 631 public void setHasSubj () { 632 mask |= HasSubj; 633 } 634 635 public void setHasPred () { 636 mask |= HasPred; 637 } 638 639 public void setHasObj () { 640 mask |= HasObj; 641 } 642 643 public void setIsStmt () { 644 mask |= IsStmt; 645 } 646 647 public boolean hasIntersect ( StmtMask m ) { 648 return (mask & m.mask) != 0; 649 } 650 651 public boolean equals ( StmtMask m ) { 652 return mask == m.mask; 653 } 654 655 } 656 657 660 public int getGraphId() { 661 return ((DBIDInt)my_GID).getIntID(); 662 } 663 664 667 public IPSet getPSet() { 668 return m_pset; 669 } 670 671 674 public DBPropLSet getDBPropLSet() { 675 return m_dbPropLSet; 676 } 677 678 697 public char subsumes ( Triple pattern, int reifBehavior ) { 698 char res = noTriplesForPattern; 699 if ( reifBehavior != GraphRDB.OPTIMIZE_ALL_REIFICATIONS_AND_HIDE_NOTHING ) 700 return res; 701 Node pred = pattern.getPredicate(); 702 if ( pred.isConcrete() ) { 703 if ( pred.equals(RDF.Nodes.subject) || 704 pred.equals(RDF.Nodes.predicate) || 705 pred.equals(RDF.Nodes.object) ) 706 res = allTriplesForPattern; 707 else if ( pred.equals(RDF.Nodes.type) ) { 708 Node obj = pattern.getObject(); 709 if ( obj.equals(RDF.Nodes.Statement) ) 710 res = allTriplesForPattern; 711 else if ( !obj.isConcrete() ) 712 res = someTriplesForPattern; 713 } 714 } else if ( (pred.isVariable()) || pred.equals(Node.ANY) ) { 715 res = someTriplesForPattern; 716 } else 717 throw new JenaException("Unexpected predicate: " + pred.toString()); 718 return res; 719 } 720 } 721 722 748 | Popular Tags |