-
Notifications
You must be signed in to change notification settings - Fork 2.3k
/
IndexReader.java
139 lines (124 loc) · 5.13 KB
/
IndexReader.java
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
/*
* Copyright (c) 2002-2017 "Neo Technology,"
* Network Engine for Objects in Lund AB [http://neotechnology.com]
*
* This file is part of Neo4j.
*
* Neo4j is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.neo4j.storageengine.api.schema;
import org.neo4j.collection.primitive.PrimitiveLongCollections;
import org.neo4j.collection.primitive.PrimitiveLongIterator;
import org.neo4j.graphdb.Resource;
import org.neo4j.internal.kernel.api.IndexQuery;
import org.neo4j.kernel.api.exceptions.index.IndexNotApplicableKernelException;
import org.neo4j.kernel.impl.newapi.IndexCursorProgressor;
import org.neo4j.values.storable.Value;
import static org.neo4j.internal.kernel.api.IndexQuery.SCAN;
/**
* Reader for an index. Must honor repeatable reads, which means that if a lookup is executed multiple times the
* same result set must be returned.
*/
public interface IndexReader extends Resource
{
/**
* @param nodeId node id to match.
* @param propertyValues property values to match.
* @return number of index entries for the given {@code nodeId} and {@code propertyValues}.
*/
long countIndexedNodes( long nodeId, Value... propertyValues );
IndexSampler createSampler();
/**
* Queries the index for the given {@link IndexQuery} predicates.
*
* @param predicates the predicates to query for.
* @return the matching entity IDs.
*/
PrimitiveLongIterator query( IndexQuery... predicates ) throws IndexNotApplicableKernelException;
/**
* @param predicates query to determine whether or not index has full number precision for.
* @return whether or not this reader will only return 100% matching results from {@link #query(IndexQuery...)}
* when calling with predicates involving numbers, such as {@link IndexQuery#exact(int, Object)}
* w/ a {@link Number} or {@link IndexQuery#range(int, Number, boolean, Number, boolean)}.
* If {@code false} is returned this means that the caller of {@link #query(IndexQuery...)} will have to
* do additional filtering, double-checking of actual property values, externally.
*/
boolean hasFullNumberPrecision( IndexQuery... predicates );
IndexReader EMPTY = new IndexReader()
{
// Used for checking index correctness
@Override
public long countIndexedNodes( long nodeId, Value... propertyValues )
{
return 0;
}
@Override
public IndexSampler createSampler()
{
return IndexSampler.EMPTY;
}
@Override
public PrimitiveLongIterator query( IndexQuery[] predicates )
{
return PrimitiveLongCollections.emptyIterator();
}
@Override
public void close()
{
}
@Override
public boolean hasFullNumberPrecision( IndexQuery... predicates )
{
return true;
}
@Override
public void query( IndexCursorProgressor.NodeValueCursor cursor, IndexQuery... query )
{
cursor.done();
}
@Override
public void scan( IndexCursorProgressor.NodeValueCursor cursor )
{
cursor.done();
}
};
default void query( IndexCursorProgressor.NodeValueCursor cursor, IndexQuery... query )
{
try
{
cursor.initialize( new NodeValueIndexProgressor( query( query ), cursor ), null );
}
catch ( IndexNotApplicableKernelException e )
{
throw new RuntimeException( "SOMEONE FORGOT TO DO EXCEPTION HANDLING", e ); // TODO: exception handling
}
}
default void scan( IndexCursorProgressor.NodeValueCursor cursor )
{
try
{
// the actual property key is ignored in the implementation, so we can pass in whatever...
// it is actually ok for the index implementation to ignore the property key under these two assumptions:
// 1. That all queries is "well formed" - i.e. we never ask for a key not in the index.
// 2. For compound indexes all nodes have all properties assigned.
// While we violate 1. here, we are at least "well intended", we don't actually care about what the key is.
// 2. holds because compound indexes are only created through node keys.
cursor.initialize( new NodeValueIndexProgressor( query( SCAN ), cursor ), null );
}
catch ( IndexNotApplicableKernelException e )
{
throw new RuntimeException( "SOMEONE FORGOT TO DO EXCEPTION HANDLING", e ); // TODO: exception handling
}
}
}