MemIRI.java
/*******************************************************************************
* Copyright (c) 2015 Eclipse RDF4J contributors, Aduna, and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Distribution License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: BSD-3-Clause
*******************************************************************************/
package org.eclipse.rdf4j.sail.memory.model;
import java.lang.ref.SoftReference;
import org.eclipse.rdf4j.model.IRI;
import org.eclipse.rdf4j.model.Value;
/**
* A MemoryStore-specific implementation of URI that stores separated namespace and local name information to enable
* reuse of namespace String objects (reducing memory usage) and that gives it node properties.
*/
public class MemIRI extends MemResource implements IRI {
private static final long serialVersionUID = 9118488004995852467L;
/*------------*
* Attributes *
*------------*/
/**
* The URI's namespace.
*/
private final String namespace;
/**
* The URI's local name.
*/
private final String localName;
/**
* The object that created this MemURI.
*/
transient private final Object creator;
/**
* The MemURI's hash code, 0 if not yet initialized.
*/
private volatile int hashCode = 0;
/**
* The list of statements for which this MemURI is the predicate.
*/
transient private final MemStatementList predicateStatements = new MemStatementList();
/**
* The list of statements for which this MemURI is the object.
*/
transient private final MemStatementList objectStatements = new MemStatementList();
/*--------------*
* Constructors *
*--------------*/
/**
* Creates a new MemURI for a URI.
*
* @param creator The object that is creating this MemURI.
* @param namespace namespace part of URI.
* @param localName localname part of URI.
*/
public MemIRI(Object creator, String namespace, String localName) {
this.creator = creator;
this.namespace = namespace;
this.localName = localName;
}
/*---------*
* Methods *
*---------*/
transient SoftReference<String> toStringCache = null;
@Override
public String toString() {
String result;
if (toStringCache == null) {
result = namespace + localName;
toStringCache = new SoftReference<>(result);
} else {
result = toStringCache.get();
if (result == null) {
result = namespace + localName;
toStringCache = new SoftReference<>(result);
}
}
return result;
}
@Override
public String stringValue() {
return toString();
}
@Override
public String getNamespace() {
return namespace;
}
@Override
public String getLocalName() {
return localName;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null) {
return false;
}
if (o.getClass() == MemIRI.class) {
MemIRI oMemIRI = (MemIRI) o;
if (oMemIRI.creator == creator) {
// two different MemIRI from the same MemoryStore can not be equal.
return false;
}
return namespace.length() == oMemIRI.namespace.length() &&
localName.length() == oMemIRI.localName.length() &&
namespace.equals(oMemIRI.namespace) &&
localName.equals(oMemIRI.localName);
}
if (o instanceof Value) {
Value oValue = (Value) o;
if (oValue.isIRI()) {
String oStr = oValue.stringValue();
if (toStringCache != null) {
String stringValue = toStringCache.get();
if (stringValue != null) {
return stringValue.equals(oStr);
}
}
return namespace.length() + localName.length() == oStr.length() &&
oStr.endsWith(localName) &&
oStr.startsWith(namespace);
}
}
return false;
}
@Override
public int hashCode() {
if (hashCode == 0) {
hashCode = stringValue().hashCode();
}
return hashCode;
}
@Override
public Object getCreator() {
return creator;
}
@Override
public boolean hasStatements() {
return !subjectStatements.isEmpty() || !predicateStatements.isEmpty() || !objectStatements.isEmpty()
|| !contextStatements.isEmpty();
}
/**
* Gets the list of statements for which this MemURI is the predicate.
*
* @return a MemStatementList containing the statements.
*/
public MemStatementList getPredicateStatementList() {
return predicateStatements;
}
/**
* Gets the number of Statements for which this MemURI is the predicate.
*
* @return An integer larger than or equal to 0.
*/
public int getPredicateStatementCount() {
return predicateStatements.size();
}
/**
* Adds a statement to this MemURI's list of statements for which it is the predicate.
*/
public void addPredicateStatement(MemStatement st) throws InterruptedException {
predicateStatements.add(st);
}
/**
* Removes statements from old snapshots (those that have expired at or before the specified snapshot version) from
* this MemValue's list of statements for which it is the predicate.
*
* @param currentSnapshot The current snapshot version.
*/
public void cleanSnapshotsFromPredicateStatements(int currentSnapshot) throws InterruptedException {
predicateStatements.cleanSnapshots(currentSnapshot);
}
@Override
public MemStatementList getObjectStatementList() {
return objectStatements;
}
@Override
public int getObjectStatementCount() {
return objectStatements.size();
}
@Override
public void addObjectStatement(MemStatement st) throws InterruptedException {
objectStatements.add(st);
}
@Override
public void cleanSnapshotsFromObjectStatements(int currentSnapshot) throws InterruptedException {
objectStatements.cleanSnapshots(currentSnapshot);
}
@Override
public boolean hasPredicateStatements() {
return !predicateStatements.isEmpty();
}
@Override
public boolean hasObjectStatements() {
return !objectStatements.isEmpty();
}
}