Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
io.sirix.index.path.summary.PathSummaryReader Maven / Gradle / Ivy
package io.sirix.index.path.summary;
import com.google.common.base.MoreObjects;
import io.sirix.access.User;
import io.sirix.access.trx.node.CommitCredentials;
import io.sirix.api.*;
import io.sirix.api.json.JsonResourceSession;
import io.sirix.axis.DescendantAxis;
import io.sirix.axis.IncludeSelf;
import io.sirix.axis.pathsummary.LevelOrderSettingInMemoryInstancesAxis;
import io.sirix.cache.Cache;
import io.sirix.cache.PathSummaryData;
import io.sirix.exception.SirixException;
import io.sirix.exception.SirixIOException;
import io.sirix.index.IndexType;
import io.sirix.node.NodeKind;
import io.sirix.node.NullNode;
import io.sirix.node.SirixDeweyID;
import io.sirix.node.immutable.json.ImmutableJsonDocumentRootNode;
import io.sirix.node.immutable.xml.ImmutableXmlDocumentRootNode;
import io.sirix.node.interfaces.NameNode;
import io.sirix.node.interfaces.StructNode;
import io.sirix.node.interfaces.immutable.ImmutableNode;
import io.sirix.node.json.JsonDocumentRootNode;
import io.sirix.page.PathSummaryPage;
import io.sirix.settings.Fixed;
import io.sirix.utils.IntToObjectMap;
import io.sirix.utils.NamePageHash;
import it.unimi.dsi.fastutil.longs.LongHash;
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
import it.unimi.dsi.fastutil.longs.LongSet;
import io.brackit.query.atomic.QNm;
import io.brackit.query.util.path.Path;
import io.brackit.query.util.path.PathException;
import org.checkerframework.checker.index.qual.NonNegative;
import io.sirix.axis.filter.FilterAxis;
import io.sirix.axis.filter.PathNameFilter;
import io.sirix.node.xml.XmlDocumentRootNode;
import java.time.Instant;
import java.util.*;
import static java.util.Objects.requireNonNull;
/**
* Path summary reader organizing the path classes of a resource.
*
* @author Johannes Lichtenberger, University of Konstanz
*/
@SuppressWarnings({ "unused", "UnusedReturnValue" })
public final class PathSummaryReader implements NodeReadOnlyTrx, NodeCursor {
/**
* Strong reference to currently selected node.
*/
private StructNode currentNode;
/**
* Page reader.
*/
private final PageReadOnlyTrx pageReadTrx;
/**
* {@link ResourceSession} reference.
*/
private final ResourceSession extends NodeReadOnlyTrx, ? extends NodeTrx> resourceSession;
/**
* Determines if path summary is closed or not.
*/
private boolean isClosed;
/**
* Mapping of a path node key to the path node/document root node.
*/
private final IntToObjectMap pathNodeMapping;
/**
* Mapping of a {@link QNm} to a set of path nodes.
*/
private final Map> qnmMapping;
/**
* The path cache.
*/
private final Map, LongSet> pathCache;
private boolean init = true;
/**
* Private constructor.
*
* @param pageReadTrx page reader
* @param resourceSession {@link ResourceSession} reference
*/
private PathSummaryReader(final PageReadOnlyTrx pageReadTrx,
final ResourceSession extends NodeReadOnlyTrx, ? extends NodeTrx> resourceSession) {
pathCache = new HashMap<>();
this.pageReadTrx = pageReadTrx;
isClosed = false;
this.resourceSession = resourceSession;
final Cache pathSummaryCache = pageReadTrx.getBufferManager().getPathSummaryCache();
final PathSummaryData pathSummaryData = pathSummaryCache.get(pageReadTrx.getRevisionNumber());
if (pathSummaryData == null || pageReadTrx.hasTrxIntentLog()) {
currentNode =
this.pageReadTrx.getRecord(Fixed.DOCUMENT_NODE_KEY.getStandardProperty(), IndexType.PATH_SUMMARY, 0);
if (currentNode == null) {
throw new IllegalStateException("Node couldn't be fetched from persistent storage!");
}
final int maxNrOfNodes =
(int) this.pageReadTrx.getPathSummaryPage(this.pageReadTrx.getActualRevisionRootPage()).getMaxNodeKey(0);
final int maxNrOfNodesForMap = (int) Math.ceil(maxNrOfNodes / 0.75);
pathNodeMapping =
new IntToObjectMap<>(maxNrOfNodes);
qnmMapping = new HashMap<>(maxNrOfNodesForMap);
boolean first = true;
boolean hasMoved = moveToFirstChild();
if (hasMoved) {
var axis = new LevelOrderSettingInMemoryInstancesAxis.Builder(this).includeSelf().build();
while (axis.hasNext()) {
final var pathNode = axis.next();
pathNodeMapping.put((int) pathNode.getNodeKey(), pathNode);
moveTo(pathNode.getNodeKey());
assert this.getNodeKey() == pathNode.getNodeKey();
qnmMapping.computeIfAbsent(this.getName(), (unused) -> new HashSet<>()).add(pathNode);
assert Objects.equals(this.getName(), pathNode.getName());
}
moveToDocumentRoot();
}
if (!pageReadTrx.hasTrxIntentLog()) {
pathSummaryCache.put(pageReadTrx.getRevisionNumber(),
new PathSummaryData(currentNode, pathNodeMapping, qnmMapping));
}
} else {
currentNode = pathSummaryData.currentNode();
pathNodeMapping = pathSummaryData.pathNodeMapping();
qnmMapping = pathSummaryData.qnmMapping();
}
init = false;
}
@Override
public Optional getUser() {
return pageReadTrx.getActualRevisionRootPage().getUser();
}
@Override
public boolean storeDeweyIDs() {
return false;
}
@Override
public PageReadOnlyTrx getPageTrx() {
return pageReadTrx;
}
/**
* Get a new path summary reader instance.
*
* @param pageReadTrx the {@link PageReadOnlyTrx} instance
* @param resourceSession the {@link ResourceSession} instance
* @return new path summary reader instance
*/
public static PathSummaryReader getInstance(final PageReadOnlyTrx pageReadTrx,
final ResourceSession extends NodeReadOnlyTrx, ? extends NodeTrx> resourceSession) {
return new PathSummaryReader(requireNonNull(pageReadTrx), requireNonNull(resourceSession));
}
// package private, only used in writer to keep the mapping always up-to-date
void putMapping(final @NonNegative long pathNodeKey, final StructNode node) {
pathNodeMapping.put((int) pathNodeKey, node);
}
// package private, only used in writer to keep the mapping always up-to-date
StructNode removeMapping(final @NonNegative long pathNodeKey) {
return pathNodeMapping.remove((int) pathNodeKey);
}
// package private, only used in writer to keep the mapping always up-to-date
void putQNameMapping(final PathNode node, final QNm name) {
final Set pathNodes = qnmMapping.computeIfAbsent(this.getName(), (unused) -> new HashSet<>());
pathNodes.add(node);
qnmMapping.put(name, pathNodes);
}
// package private, only used in writer to keep the mapping always up-to-date
void removeQNameMapping(final @NonNegative PathNode node, final QNm name) {
final Set pathNodes = qnmMapping.computeIfAbsent(this.getName(), (unused) -> new HashSet<>());
if (pathNodes.size() == 1) {
qnmMapping.remove(name);
} else {
pathNodes.remove(node);
}
}
/**
* Match all descendants of the node denoted by its {@code pathNodeKey} with the given {@code name}.
*
* @param name the QName
* @param pathNodeKey the path node key to start the search from
* @param includeSelf if current node should be included or not
* @return a set with bits set for each matching path node (its {@code pathNodeKey})
*/
public BitSet matchDescendants(final QNm name, final @NonNegative long pathNodeKey, final IncludeSelf includeSelf) {
assertNotClosed();
final Set set = qnmMapping.get(name);
if (set == null) {
return new BitSet(0);
}
moveTo(pathNodeKey);
final BitSet matches = new BitSet();
for (final long nodeKey : new FilterAxis<>(new DescendantAxis(this, includeSelf),
new PathNameFilter(this, name.toString()))) {
matches.set((int) nodeKey);
}
return matches;
}
/**
* Match a {@link QNm} with a minimum level.
*
* @param name the QName
* @param minLevel minimum level
* @return a set with bits set for each matching path node
*/
public BitSet match(final QNm name, final @NonNegative int minLevel) {
assertNotClosed();
final Set set = qnmMapping.get(name);
if (set == null) {
return new BitSet(0);
}
final BitSet matches = new BitSet();
for (final PathNode psn : set) {
if (psn.getLevel() >= minLevel) {
matches.set((int) psn.getNodeKey());
}
}
return matches;
}
/**
* Match a {@link QNm} with a minimum level.
*
* @param name the QName
* @param minLevel minimum level
* @return a set with bits set for each matching path node
*/
public BitSet match(final QNm name, final @NonNegative int minLevel, NodeKind nodeKind) {
assertNotClosed();
final Set set = qnmMapping.get(name);
if (set == null) {
return new BitSet(0);
}
final BitSet matches = new BitSet();
for (final PathNode psn : set) {
if (psn.getLevel() >= minLevel && psn.getPathKind() == nodeKind) {
matches.set((int) psn.getNodeKey());
}
}
return matches;
}
/**
* Match a {@link QNm} with a specific level.
*
* @param name the QName
* @param level minimum level
* @param nodeKind the node type
* @return a set with bits set for each matching path node
*/
public Optional matchLevel(final QNm name, final @NonNegative int level, NodeKind nodeKind) {
assertNotClosed();
final Set set = qnmMapping.get(name);
if (set == null) {
return Optional.empty();
}
for (final PathNode pathNode : set) {
if (pathNode.getLevel() == level && pathNode.getPathKind() == nodeKind) {
return Optional.of(pathNode);
}
}
return Optional.empty();
}
/**
* Get a set of PCRs matching the specified collection of paths
*
* @param expressions the paths to lookup
* @return a set of PCRs matching the specified collection of paths
* @throws SirixException if parsing a path fails
*/
public LongSet getPCRsForPaths(final Collection> expressions) throws PathException {
assertNotClosed();
final LongSet pcrs = new LongOpenHashSet();
for (final Path path : expressions) {
pcrs.addAll(getPCRsForPath(path));
}
return pcrs;
}
/**
* Get the path node corresponding to the key.
*
* @param pathNodeKey path node key
* @return path node corresponding to the provided key
*/
public PathNode getPathNodeForPathNodeKey(final @NonNegative long pathNodeKey) {
assertNotClosed();
return (PathNode) pathNodeMapping.get((int) pathNodeKey);
}
@Override
public ImmutableNode getNode() {
assertNotClosed();
if (currentNode instanceof XmlDocumentRootNode) {
return ImmutableXmlDocumentRootNode.of((XmlDocumentRootNode) currentNode);
} else if (currentNode instanceof JsonDocumentRootNode) {
return ImmutableJsonDocumentRootNode.of((JsonDocumentRootNode) currentNode);
}
return ImmutablePathNode.of((PathNode) currentNode);
}
/**
* Get path class records (PCRs) for the specified path.
*
* @param path the path for which to get a set of PCRs
* @return set of PCRs belonging to the specified path
* @throws SirixException if anything went wrong
*/
public LongSet getPCRsForPath(final Path path) throws PathException {
var pcrSet = pathCache.get(path);
if (pcrSet != null) {
return pcrSet;
}
pcrSet = new LongOpenHashSet();
final boolean isAttributePattern = path.isAttribute();
final int pathLength = path.getLength();
final long nodeKey = currentNode.getNodeKey();
moveToDocumentRoot();
for (final Axis axis = new DescendantAxis(this); axis.hasNext(); ) {
axis.nextLong();
final PathNode node = this.getPathNode();
if (node == null) {
continue;
}
if (node.getLevel() < pathLength) {
continue;
}
if (isAttributePattern ^ (node.getPathKind() == NodeKind.ATTRIBUTE)) {
continue;
}
final Path nodePath = getPath();
assert nodePath != null;
if (path.matches(nodePath)) {
pcrSet.add(node.getNodeKey());
}
}
moveTo(nodeKey);
pathCache.put(path, pcrSet);
return pcrSet;
}
@Override
public boolean hasChildren() {
assertNotClosed();
return getStructuralNode().getChildCount() > 0;
}
/**
* Get a path node.
*
* @return {@link PathNode} reference or null for the document root.
*/
public PathNode getPathNode() {
assertNotClosed();
if (currentNode instanceof PathNode) {
return (PathNode) currentNode;
}
return null;
}
@Override
public boolean moveTo(final long nodeKey) {
assertNotClosed();
if (!init && nodeKey != 0) {
final PathNode node = (PathNode) pathNodeMapping.get((int) nodeKey);
if (node != null) {
currentNode = node;
return true;
} else {
return false;
}
}
// Remember old node and fetch new one.
final StructNode oldNode = currentNode;
StructNode newNode;
try {
newNode = pageReadTrx.getRecord(nodeKey, IndexType.PATH_SUMMARY, 0);
} catch (final SirixIOException e) {
newNode = null;
}
if (newNode == null) {
currentNode = oldNode;
return false;
} else {
currentNode = newNode;
return true;
}
}
@Override
public boolean moveToParent() {
assertNotClosed();
if (!getStructuralNode().hasParent()) {
return false;
}
final var node = getStructuralNode();
if (node instanceof PathNode pathNode && pathNode.getParent() != null) {
currentNode = pathNode.getParent();
return true;
}
return moveTo(getStructuralNode().getParentKey());
}
@Override
public boolean moveToFirstChild() {
assertNotClosed();
if (!getStructuralNode().hasFirstChild()) {
return false;
}
final var node = getStructuralNode();
if (node instanceof PathNode pathNode && pathNode.getFirstChild() != null) {
currentNode = pathNode.getFirstChild();
return true;
}
return moveTo(getStructuralNode().getFirstChildKey());
}
@Override
public boolean moveToLeftSibling() {
assertNotClosed();
if (!getStructuralNode().hasLeftSibling()) {
return false;
}
final var node = getStructuralNode();
if (node instanceof PathNode pathNode && pathNode.getLeftSibling() != null) {
currentNode = pathNode.getLeftSibling();
return true;
}
return moveTo(getStructuralNode().getLeftSiblingKey());
}
@Override
public boolean moveToRightSibling() {
assertNotClosed();
if (!getStructuralNode().hasRightSibling()) {
return false;
}
final var node = getStructuralNode();
if (node instanceof PathNode pathNode && pathNode.getRightSibling() != null) {
currentNode = pathNode.getRightSibling();
return true;
}
return moveTo(getStructuralNode().getRightSiblingKey());
}
@Override
public void close() {
if (!isClosed) {
// Immediately release all references.
currentNode = null;
isClosed = true;
if (pageReadTrx != null && !pageReadTrx.isClosed()) {
pageReadTrx.close();
}
}
}
/**
* Make sure that the path summary is not yet closed when calling this method.
*/
private void assertNotClosed() {
if (isClosed) {
throw new IllegalStateException("Path summary is already closed.");
}
}
@Override
public boolean moveToDocumentRoot() {
return moveTo(Fixed.DOCUMENT_NODE_KEY.getStandardProperty());
}
/**
* Get the current node as a structural node.
*
* @return structural node
*/
private StructNode getStructuralNode() {
if (currentNode != null) {
return currentNode;
}
return new NullNode(null);
}
@Override
public long getId() {
throw new UnsupportedOperationException();
}
@Override
public int getRevisionNumber() {
assertNotClosed();
return pageReadTrx.getRevisionNumber();
}
@Override
public Instant getRevisionTimestamp() {
assertNotClosed();
return Instant.ofEpochMilli(pageReadTrx.getActualRevisionRootPage().getRevisionTimestamp());
}
@Override
public long getMaxNodeKey() {
assertNotClosed();
final var pageReference = pageReadTrx.getActualRevisionRootPage().getPathSummaryPageReference();
if (pageReference.getPage() == null) {
pageReference.setPage(pageReadTrx.getReader().read(pageReference, pageReadTrx));
}
return ((PathSummaryPage) pageReference.getPage()).getMaxNodeKey(0);
}
@Override
public boolean moveToNextFollowing() {
assertNotClosed();
while (!getStructuralNode().hasRightSibling() && currentNode.hasParent()) {
moveToParent();
}
return moveToRightSibling();
}
@Override
public QNm getName() {
assertNotClosed();
if (currentNode instanceof NameNode nameNode) {
final QNm name = nameNode.getName();
if (name != null) {
return nameNode.getName();
}
final int uriKey = nameNode.getURIKey();
final String uri = uriKey == -1 || pageReadTrx.getResourceSession() instanceof JsonResourceSession
? ""
: pageReadTrx.getName(nameNode.getURIKey(), NodeKind.NAMESPACE);
final int prefixKey = nameNode.getPrefixKey();
final String prefix =
prefixKey == -1 ? "" : pageReadTrx.getName(prefixKey, ((PathNode) currentNode).getPathKind());
final int localNameKey = nameNode.getLocalNameKey();
final String localName =
localNameKey == -1 ? "" : pageReadTrx.getName(localNameKey, ((PathNode) currentNode).getPathKind());
final var qNm = new QNm(uri, prefix, localName);
if (nameNode instanceof PathNode pathNode) {
pathNode.setName(qNm);
}
return qNm;
} else {
return null;
}
}
@Override
public int keyForName(final String pName) {
assertNotClosed();
return NamePageHash.generateHashForString(pName);
}
@Override
public String nameForKey(final int key) {
assertNotClosed();
if (currentNode instanceof PathNode node) {
return pageReadTrx.getName(key, node.getPathKind());
} else {
return "";
}
}
@Override
public boolean isClosed() {
return isClosed;
}
@Override
public ResourceSession extends NodeReadOnlyTrx, ? extends NodeTrx> getResourceSession() {
assertNotClosed();
return resourceSession;
}
@Override
public boolean moveToLastChild() {
assertNotClosed();
if (getStructuralNode().hasFirstChild()) {
moveToFirstChild();
while (getStructuralNode().hasRightSibling()) {
moveToRightSibling();
}
return true;
}
return false;
}
/**
* Get the path up to the root path node.
*
* @return path up to the root
*/
public Path getPath() {
PathNode currNode = getPathNode();
PathNode node = currNode;
if (node == null) {
moveToFirstChild();
node = getPathNode();
if (node == null) {
return null;
}
}
final Path pathFromNode = node.getPath();
if (pathFromNode != null) {
return pathFromNode;
}
final long nodeKey = getNodeKey();
moveTo(node.getNodeKey());
final PathNode[] paths = new PathNode[node.getLevel()];
for (int i = node.getLevel() - 1; i >= 0; i--) {
paths[i] = node;
moveToParent();
node = getPathNode();
}
final Path path = new Path<>();
for (final PathNode pathNode : paths) {
moveTo(pathNode.getNodeKey());
if (pathNode.getPathKind() == NodeKind.ATTRIBUTE) {
path.attribute(getName());
} else if (pathNode.getPathKind() == NodeKind.ARRAY) {
path.childArray();
} else if (pathNode.getPathKind() == NodeKind.OBJECT_KEY) {
path.childObjectField(getName());
} else {
path.child(getName());
}
}
moveTo(nodeKey);
assert currNode != null;
currNode.setPath(path);
return path;
}
@Override
public String toString() {
final MoreObjects.ToStringHelper helper = MoreObjects.toStringHelper(this);
if (currentNode instanceof PathNode node) {
helper.add("uri", pageReadTrx.getName(node.getURIKey(), node.getPathKind()));
helper.add("prefix", pageReadTrx.getName(node.getPrefixKey(), node.getPathKind()));
helper.add("localName", pageReadTrx.getName(node.getLocalNameKey(), node.getPathKind()));
}
helper.add("node", currentNode);
return helper.toString();
}
/**
* Get level of currently selected path node.
*
* @return level of currently selected path node
*/
public int getLevel() {
assertNotClosed();
if (currentNode instanceof PathNode) {
assert getPathNode() != null;
return getPathNode().getLevel();
}
return 0;
}
@Override
public boolean hasNode(final @NonNegative long key) {
assertNotClosed();
final long currNodeKey = currentNode.getNodeKey();
final boolean retVal = moveTo(key);
final boolean movedBack = moveTo(currNodeKey);
assert movedBack : "moveTo(currNodeKey) must succeed!";
return retVal;
}
@Override
public boolean hasParent() {
assertNotClosed();
return currentNode.hasParent();
}
@Override
public boolean hasFirstChild() {
assertNotClosed();
return getStructuralNode().hasFirstChild();
}
@Override
public boolean hasLastChild() {
assertNotClosed();
// If it has a first child it also has a last child :)
return getStructuralNode().hasFirstChild();
}
@Override
public boolean hasLeftSibling() {
assertNotClosed();
return getStructuralNode().hasLeftSibling();
}
@Override
public boolean hasRightSibling() {
assertNotClosed();
return getStructuralNode().hasRightSibling();
}
@Override
public long getNodeKey() {
assertNotClosed();
return currentNode.getNodeKey();
}
@Override
public long getLeftSiblingKey() {
assertNotClosed();
return getStructuralNode().getLeftSiblingKey();
}
@Override
public long getRightSiblingKey() {
assertNotClosed();
return getStructuralNode().getRightSiblingKey();
}
@Override
public long getFirstChildKey() {
assertNotClosed();
return getStructuralNode().getFirstChildKey();
}
@Override
public long getLastChildKey() {
assertNotClosed();
if (getStructuralNode().hasFirstChild()) {
moveToFirstChild();
while (getStructuralNode().hasRightSibling()) {
moveToRightSibling();
}
return currentNode.getNodeKey();
}
return Fixed.NULL_NODE_KEY.getStandardProperty();
}
@Override
public long getParentKey() {
assertNotClosed();
return currentNode.getParentKey();
}
@Override
public NodeKind getKind() {
assertNotClosed();
return currentNode.getKind();
}
@Override
public long getPathNodeKey() {
assertNotClosed();
return -1;
}
@Override
public NodeKind getPathKind() {
assertNotClosed();
if (currentNode instanceof PathNode) {
return ((PathNode) currentNode).getPathKind();
}
return NodeKind.NULL;
}
@Override
public long getChildCount() {
assertNotClosed();
return getStructuralNode().getChildCount();
}
@Override
public long getDescendantCount() {
assertNotClosed();
return getStructuralNode().getDescendantCount();
}
@Override
public NodeKind getFirstChildKind() {
assertNotClosed();
return NodeKind.PATH;
}
@Override
public NodeKind getLastChildKind() {
assertNotClosed();
return NodeKind.PATH;
}
@Override
public NodeKind getLeftSiblingKind() {
assertNotClosed();
return NodeKind.PATH;
}
@Override
public NodeKind getParentKind() {
assertNotClosed();
if (currentNode.getParentKey() == Fixed.DOCUMENT_NODE_KEY.getStandardProperty()) {
final var currentStructNode = getStructuralNode();
moveToParent();
final var parentKind = currentNode.getKind();
currentNode = currentStructNode;
return parentKind;
}
if (currentNode.getParentKey() == Fixed.NULL_NODE_KEY.getStandardProperty()) {
return NodeKind.UNKNOWN;
}
return NodeKind.PATH;
}
@Override
public NodeKind getRightSiblingKind() {
assertNotClosed();
return NodeKind.PATH;
}
/**
* Get references.
*
* @return number of references of a node
*/
public int getReferences() {
assertNotClosed();
if (currentNode.getKind() == NodeKind.XML_DOCUMENT) {
return 1;
} else {
assert getPathNode() != null;
return getPathNode().getReferences();
}
}
@Override
public boolean isDocumentRoot() {
assertNotClosed();
return currentNode.getKind() == NodeKind.XML_DOCUMENT || currentNode.getKind() == NodeKind.JSON_DOCUMENT;
}
@Override
public boolean moveToPrevious() {
assertNotClosed();
final StructNode node = getStructuralNode();
if (node.hasLeftSibling()) {
// Left sibling node.
boolean leftSiblMove = moveTo(node.getLeftSiblingKey());
// Now move down to rightmost descendant node if it has one.
while (hasFirstChild()) {
moveToLastChild();
}
return leftSiblMove;
}
// Parent node.
return moveTo(node.getParentKey());
}
@Override
public boolean moveToNext() {
assertNotClosed();
final StructNode node = getStructuralNode();
if (node.hasRightSibling()) {
// Right sibling node.
return moveTo(node.getRightSiblingKey());
}
// Next following node.
return moveToNextFollowing();
}
@Override
public CommitCredentials getCommitCredentials() {
assertNotClosed();
return pageReadTrx.getCommitCredentials();
}
public boolean isNameNode() {
assertNotClosed();
return currentNode instanceof NameNode;
}
public int getLocalNameKey() {
assertNotClosed();
if (currentNode instanceof NameNode) {
return ((NameNode) currentNode).getLocalNameKey();
}
return -1;
}
public int getPrefixKey() {
assertNotClosed();
if (currentNode instanceof NameNode nameNode) {
return nameNode.getPrefixKey();
}
return -1;
}
@Override
public long getHash() {
throw new UnsupportedOperationException();
}
@Override
public String getValue() {
throw new UnsupportedOperationException();
}
@Override
public SirixDeweyID getDeweyID() {
throw new UnsupportedOperationException();
}
@Override
public int getPreviousRevisionNumber() {
throw new UnsupportedOperationException();
}
public void clearCache() {
pathCache.clear();
}
public void removeFromCache(final QNm name) {
pathCache.keySet().removeIf(path -> path.tail().equals(name));
}
private static class DictionaryHashStrategy implements LongHash.Strategy {
@Override
public int hashCode(long l) {
return (int) (l ^ (l >>> 32));
}
@Override
public boolean equals(long l1, long l2) {
return l1 == l2;
}
}
}