-
Notifications
You must be signed in to change notification settings - Fork 2.3k
/
BasePlanner.scala
114 lines (97 loc) · 4.37 KB
/
BasePlanner.scala
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
/*
* Copyright (c) 2002-2018 "Neo4j,"
* Neo4j Sweden AB [http://neo4j.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.cypher.internal.compatibility
import java.time.Clock
import org.neo4j.cypher.internal._
import org.neo4j.cypher.internal.compatibility.v3_5.{WrappedMonitors => WrappedMonitorsv3_5}
import org.neo4j.cypher.internal.compiler.v3_5._
import org.neo4j.cypher.internal.compiler.v3_5.phases.LogicalPlanState
import org.neo4j.cypher.internal.planner.v3_5.spi.PlanContext
import org.neo4j.helpers.collection.Pair
import org.neo4j.kernel.monitoring.{Monitors => KernelMonitors}
import org.neo4j.logging.Log
import org.neo4j.values.virtual.MapValue
import org.opencypher.v9_0.frontend.phases._
/**
* Base planner.
*
* @tparam STATEMENT type of AST statement used by this planner.
* @tparam PARSED_STATE type of the state which represents a parsed query.
*/
abstract class BasePlanner[STATEMENT <: AnyRef, PARSED_STATE <: AnyRef](
config: CypherPlannerConfiguration,
clock: Clock,
kernelMonitors: KernelMonitors,
log: Log,
txIdProvider: () => Long
) extends CachingPlanner[PARSED_STATE] {
protected val logger: InfoLogger = new StringInfoLogger(log)
protected val monitors: Monitors = WrappedMonitorsv3_5(kernelMonitors)
protected val cacheTracer: CacheTracer[Pair[STATEMENT, MapValue]] = monitors.newMonitor[CacheTracer[Pair[STATEMENT, MapValue]]]("cypher3.5")
override def parserCacheSize: Int = config.queryCacheSize
protected val planCache: AstLogicalPlanCache[STATEMENT] =
new AstLogicalPlanCache(config.queryCacheSize,
cacheTracer,
clock,
config.statsDivergenceCalculator,
txIdProvider)
override def clearCaches(): Long = {
Math.max(super.clearCaches(), planCache.clear())
}
protected def logStalePlanRemovalMonitor(log: InfoLogger): CacheTracer[STATEMENT] =
new CacheTracer[STATEMENT] {
override def queryCacheStale(key: STATEMENT, secondsSinceReplan: Int, metaData: String) {
log.info(s"Discarded stale query from the query cache after $secondsSinceReplan seconds: $metaData")
}
override def queryCacheHit(queryKey: STATEMENT, metaData: String): Unit = {}
override def queryCacheMiss(queryKey: STATEMENT, metaData: String): Unit = {}
override def queryCacheFlush(sizeOfCacheBeforeFlush: Long): Unit = {}
}
protected def createReusabilityState(logicalPlanState: LogicalPlanState,
planContext: PlanContext): ReusabilityState = {
if (ProcedureCallOrSchemaCommandRuntime
.logicalToExecutable
.isDefinedAt(logicalPlanState.maybeLogicalPlan.get))
FineToReuse
else {
val fp = PlanFingerprint.take(clock, planContext.txIdProvider, planContext.statistics)
val fingerprint = new PlanFingerprintReference(fp)
MaybeReusable(fingerprint)
}
}
}
trait CypherCacheFlushingMonitor {
def cacheFlushDetected(sizeBeforeFlush: Long) {}
}
trait CypherCacheHitMonitor[T] {
def cacheHit(key: T) {}
def cacheMiss(key: T) {}
def cacheDiscard(key: T, userKey: String, secondsSinceReplan: Int) {}
}
trait CypherCacheMonitor[T] extends CypherCacheHitMonitor[T] with CypherCacheFlushingMonitor
trait AstCacheMonitor[STATEMENT <: AnyRef] extends CypherCacheMonitor[STATEMENT]
trait InfoLogger {
def info(message: String)
}
class StringInfoLogger(log: Log) extends InfoLogger {
def info(message: String) {
log.info(message)
}
}