Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
5b87daab
Unverified
提交
5b87daab
authored
6 年前
作者:
Evgenij Ryazanov
提交者:
GitHub
6 年前
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #1464 from katzyn/window
Assorted minor changes in window processing code
上级
b79444bd
d10900d4
显示空白字符变更
内嵌
并排
正在显示
17 个修改的文件
包含
250 行增加
和
208 行删除
+250
-208
SelectGroups.java
h2/src/main/org/h2/command/dml/SelectGroups.java
+45
-23
AbstractAggregate.java
...c/main/org/h2/expression/aggregate/AbstractAggregate.java
+59
-3
AggregateDataHistogram.java
...n/org/h2/expression/aggregate/AggregateDataHistogram.java
+2
-2
AggregateDataMode.java
...c/main/org/h2/expression/aggregate/AggregateDataMode.java
+1
-1
DataAnalysisOperation.java
...in/org/h2/expression/aggregate/DataAnalysisOperation.java
+43
-114
PartitionData.java
h2/src/main/org/h2/expression/aggregate/PartitionData.java
+1
-1
Window.java
h2/src/main/org/h2/expression/aggregate/Window.java
+11
-7
WindowFunction.java
h2/src/main/org/h2/expression/aggregate/WindowFunction.java
+31
-40
HashIndex.java
h2/src/main/org/h2/index/HashIndex.java
+1
-1
NonUniqueHashIndex.java
h2/src/main/org/h2/index/NonUniqueHashIndex.java
+1
-1
LocalResultImpl.java
h2/src/main/org/h2/result/LocalResultImpl.java
+3
-3
ValueHashMap.java
h2/src/main/org/h2/util/ValueHashMap.java
+0
-9
ValueArray.java
h2/src/main/org/h2/value/ValueArray.java
+14
-0
count.sql
...rc/test/org/h2/test/scripts/functions/aggregate/count.sql
+11
-0
lead.sql
h2/src/test/org/h2/test/scripts/functions/window/lead.sql
+8
-0
row_number.sql
.../test/org/h2/test/scripts/functions/window/row_number.sql
+17
-1
TestValueHashMap.java
h2/src/test/org/h2/test/unit/TestValueHashMap.java
+2
-2
没有找到文件。
h2/src/main/org/h2/command/dml/SelectGroups.java
浏览文件 @
5b87daab
...
@@ -15,6 +15,8 @@ import java.util.Map.Entry;
...
@@ -15,6 +15,8 @@ import java.util.Map.Entry;
import
org.h2.engine.Session
;
import
org.h2.engine.Session
;
import
org.h2.expression.Expression
;
import
org.h2.expression.Expression
;
import
org.h2.expression.aggregate.DataAnalysisOperation
;
import
org.h2.expression.aggregate.DataAnalysisOperation
;
import
org.h2.expression.aggregate.PartitionData
;
import
org.h2.util.ValueHashMap
;
import
org.h2.value.Value
;
import
org.h2.value.Value
;
import
org.h2.value.ValueArray
;
import
org.h2.value.ValueArray
;
...
@@ -62,12 +64,6 @@ public abstract class SelectGroups {
...
@@ -62,12 +64,6 @@ public abstract class SelectGroups {
*/
*/
private
Iterator
<
Entry
<
ValueArray
,
Object
[]>>
cursor
;
private
Iterator
<
Entry
<
ValueArray
,
Object
[]>>
cursor
;
/**
* The key for the default group.
*/
// Can be static, but TestClearReferences complains about it
private
final
ValueArray
defaultGroup
=
ValueArray
.
get
(
new
Value
[
0
]);
Grouped
(
Session
session
,
ArrayList
<
Expression
>
expressions
,
int
[]
groupIndex
)
{
Grouped
(
Session
session
,
ArrayList
<
Expression
>
expressions
,
int
[]
groupIndex
)
{
super
(
session
,
expressions
);
super
(
session
,
expressions
);
this
.
groupIndex
=
groupIndex
;
this
.
groupIndex
=
groupIndex
;
...
@@ -84,7 +80,7 @@ public abstract class SelectGroups {
...
@@ -84,7 +80,7 @@ public abstract class SelectGroups {
@Override
@Override
public
void
nextSource
()
{
public
void
nextSource
()
{
if
(
groupIndex
==
null
)
{
if
(
groupIndex
==
null
)
{
currentGroupsKey
=
defaultGroup
;
currentGroupsKey
=
ValueArray
.
getEmpty
()
;
}
else
{
}
else
{
Value
[]
keyValues
=
new
Value
[
groupIndex
.
length
];
Value
[]
keyValues
=
new
Value
[
groupIndex
.
length
];
// update group
// update group
...
@@ -97,7 +93,7 @@ public abstract class SelectGroups {
...
@@ -97,7 +93,7 @@ public abstract class SelectGroups {
}
}
Object
[]
values
=
groupByData
.
get
(
currentGroupsKey
);
Object
[]
values
=
groupByData
.
get
(
currentGroupsKey
);
if
(
values
==
null
)
{
if
(
values
==
null
)
{
values
=
new
Object
[
Math
.
max
(
exprToIndexInGroupByData
.
size
(),
expressions
.
size
())]
;
values
=
createRow
()
;
groupByData
.
put
(
currentGroupsKey
,
values
);
groupByData
.
put
(
currentGroupsKey
,
values
);
}
}
currentGroupByExprData
=
values
;
currentGroupByExprData
=
values
;
...
@@ -118,8 +114,7 @@ public abstract class SelectGroups {
...
@@ -118,8 +114,7 @@ public abstract class SelectGroups {
public
void
done
()
{
public
void
done
()
{
super
.
done
();
super
.
done
();
if
(
groupIndex
==
null
&&
groupByData
.
size
()
==
0
)
{
if
(
groupIndex
==
null
&&
groupByData
.
size
()
==
0
)
{
groupByData
.
put
(
defaultGroup
,
groupByData
.
put
(
ValueArray
.
getEmpty
(),
createRow
());
new
Object
[
Math
.
max
(
exprToIndexInGroupByData
.
size
(),
expressions
.
size
())]);
}
}
cursor
=
groupByData
.
entrySet
().
iterator
();
cursor
=
groupByData
.
entrySet
().
iterator
();
}
}
...
@@ -164,7 +159,7 @@ public abstract class SelectGroups {
...
@@ -164,7 +159,7 @@ public abstract class SelectGroups {
@Override
@Override
public
void
nextSource
()
{
public
void
nextSource
()
{
Object
[]
values
=
new
Object
[
Math
.
max
(
exprToIndexInGroupByData
.
size
(),
expressions
.
size
())]
;
Object
[]
values
=
createRow
()
;
rows
.
add
(
values
);
rows
.
add
(
values
);
currentGroupByExprData
=
values
;
currentGroupByExprData
=
values
;
currentGroupRowId
++;
currentGroupRowId
++;
...
@@ -184,10 +179,9 @@ public abstract class SelectGroups {
...
@@ -184,10 +179,9 @@ public abstract class SelectGroups {
@Override
@Override
public
ValueArray
next
()
{
public
ValueArray
next
()
{
if
(
cursor
.
hasNext
())
{
if
(
cursor
.
hasNext
())
{
Object
[]
values
=
cursor
.
next
();
currentGroupByExprData
=
cursor
.
next
();
currentGroupByExprData
=
values
;
currentGroupRowId
++;
currentGroupRowId
++;
return
ValueArray
.
get
(
new
Value
[
0
]
);
return
ValueArray
.
get
Empty
(
);
}
}
return
null
;
return
null
;
}
}
...
@@ -206,12 +200,17 @@ public abstract class SelectGroups {
...
@@ -206,12 +200,17 @@ public abstract class SelectGroups {
* Maps an expression object to an index, to use in accessing the Object[]
* Maps an expression object to an index, to use in accessing the Object[]
* pointed to by groupByData.
* pointed to by groupByData.
*/
*/
final
HashMap
<
Expression
,
Integer
>
exprToIndexInGroupByData
=
new
HashMap
<>();
private
final
HashMap
<
Expression
,
Integer
>
exprToIndexInGroupByData
=
new
HashMap
<>();
/**
/**
* Maps an expression object to its data.
* Maps an
window
expression object to its data.
*/
*/
private
final
HashMap
<
DataAnalysisOperation
,
Object
>
windowData
=
new
HashMap
<>();
private
final
HashMap
<
DataAnalysisOperation
,
PartitionData
>
windowData
=
new
HashMap
<>();
/**
* Maps an partitioned window expression object to its data.
*/
private
final
HashMap
<
DataAnalysisOperation
,
ValueHashMap
<
PartitionData
>>
windowPartitionData
=
new
HashMap
<>();
/**
/**
* The id of the current group.
* The id of the current group.
...
@@ -286,15 +285,26 @@ public abstract class SelectGroups {
...
@@ -286,15 +285,26 @@ public abstract class SelectGroups {
currentGroupByExprData
[
index
]
=
obj
;
currentGroupByExprData
[
index
]
=
obj
;
}
}
final
Object
[]
createRow
()
{
return
new
Object
[
Math
.
max
(
exprToIndexInGroupByData
.
size
(),
expressions
.
size
())];
}
/**
/**
* Get the window data for the specified expression.
* Get the window data for the specified expression.
*
*
* @param expr
* @param expr
* expression
* expression
* @param partitionKey
* a key of partition
* @return expression data or null
* @return expression data or null
*/
*/
public
final
Object
getWindowExprData
(
DataAnalysisOperation
expr
)
{
public
final
PartitionData
getWindowExprData
(
DataAnalysisOperation
expr
,
Value
partitionKey
)
{
if
(
partitionKey
==
null
)
{
return
windowData
.
get
(
expr
);
return
windowData
.
get
(
expr
);
}
else
{
ValueHashMap
<
PartitionData
>
map
=
windowPartitionData
.
get
(
expr
);
return
map
!=
null
?
map
.
get
(
partitionKey
)
:
null
;
}
}
}
/**
/**
...
@@ -302,12 +312,23 @@ public abstract class SelectGroups {
...
@@ -302,12 +312,23 @@ public abstract class SelectGroups {
*
*
* @param expr
* @param expr
* expression
* expression
* @param partitionKey
* a key of partition
* @param object
* @param object
* expression data to set
*
window
expression data to set
*/
*/
public
final
void
setWindowExprData
(
DataAnalysisOperation
expr
,
Object
obj
)
{
public
final
void
setWindowExprData
(
DataAnalysisOperation
expr
,
Value
partitionKey
,
PartitionData
obj
)
{
if
(
partitionKey
==
null
)
{
Object
old
=
windowData
.
put
(
expr
,
obj
);
Object
old
=
windowData
.
put
(
expr
,
obj
);
assert
old
==
null
;
assert
old
==
null
;
}
else
{
ValueHashMap
<
PartitionData
>
map
=
windowPartitionData
.
get
(
expr
);
if
(
map
==
null
)
{
map
=
new
ValueHashMap
<>();
windowPartitionData
.
put
(
expr
,
map
);
}
map
.
put
(
partitionKey
,
obj
);
}
}
}
abstract
void
updateCurrentGroupExprData
();
abstract
void
updateCurrentGroupExprData
();
...
@@ -329,6 +350,7 @@ public abstract class SelectGroups {
...
@@ -329,6 +350,7 @@ public abstract class SelectGroups {
currentGroupByExprData
=
null
;
currentGroupByExprData
=
null
;
exprToIndexInGroupByData
.
clear
();
exprToIndexInGroupByData
.
clear
();
windowData
.
clear
();
windowData
.
clear
();
windowPartitionData
.
clear
();
currentGroupRowId
=
0
;
currentGroupRowId
=
0
;
}
}
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/expression/aggregate/AbstractAggregate.java
浏览文件 @
5b87daab
...
@@ -6,6 +6,8 @@
...
@@ -6,6 +6,8 @@
package
org
.
h2
.
expression
.
aggregate
;
package
org
.
h2
.
expression
.
aggregate
;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
java.util.HashMap
;
import
java.util.Iterator
;
import
org.h2.command.dml.Select
;
import
org.h2.command.dml.Select
;
import
org.h2.command.dml.SelectGroups
;
import
org.h2.command.dml.SelectGroups
;
...
@@ -14,6 +16,7 @@ import org.h2.engine.Session;
...
@@ -14,6 +16,7 @@ import org.h2.engine.Session;
import
org.h2.expression.Expression
;
import
org.h2.expression.Expression
;
import
org.h2.table.ColumnResolver
;
import
org.h2.table.ColumnResolver
;
import
org.h2.table.TableFilter
;
import
org.h2.table.TableFilter
;
import
org.h2.value.Value
;
/**
/**
* A base class for aggregate functions.
* A base class for aggregate functions.
...
@@ -68,14 +71,67 @@ public abstract class AbstractAggregate extends DataAnalysisOperation {
...
@@ -68,14 +71,67 @@ public abstract class AbstractAggregate extends DataAnalysisOperation {
super
.
setEvaluatable
(
tableFilter
,
b
);
super
.
setEvaluatable
(
tableFilter
,
b
);
}
}
@Override
protected
void
getOrderedResultLoop
(
Session
session
,
HashMap
<
Integer
,
Value
>
result
,
ArrayList
<
Value
[]>
ordered
,
int
rowIdColumn
)
{
WindowFrame
frame
=
over
.
getWindowFrame
();
if
(
frame
==
null
||
frame
.
isDefault
())
{
// Aggregate all values before the current row (including)
Object
aggregateData
=
createAggregateData
();
for
(
Value
[]
row
:
ordered
)
{
// Collect values one by one
updateFromExpressions
(
session
,
aggregateData
,
row
);
result
.
put
(
row
[
rowIdColumn
].
getInt
(),
getAggregatedValue
(
session
,
aggregateData
));
}
}
else
if
(
frame
.
isFullPartition
())
{
// Aggregate values from the whole partition
Object
aggregateData
=
createAggregateData
();
for
(
Value
[]
row
:
ordered
)
{
updateFromExpressions
(
session
,
aggregateData
,
row
);
}
// All rows have the same value
Value
value
=
getAggregatedValue
(
session
,
aggregateData
);
for
(
Value
[]
row
:
ordered
)
{
result
.
put
(
row
[
rowIdColumn
].
getInt
(),
value
);
}
}
else
{
// All other types of frames (slow)
int
size
=
ordered
.
size
();
for
(
int
i
=
0
;
i
<
size
;
i
++)
{
Object
aggregateData
=
createAggregateData
();
for
(
Iterator
<
Value
[]>
iter
=
frame
.
iterator
(
session
,
ordered
,
getOverOrderBySort
(),
i
,
false
);
iter
.
hasNext
();)
{
updateFromExpressions
(
session
,
aggregateData
,
iter
.
next
());
}
result
.
put
(
ordered
.
get
(
i
)[
rowIdColumn
].
getInt
(),
getAggregatedValue
(
session
,
aggregateData
));
}
}
}
/**
* Updates the provided aggregate data from the remembered expressions.
*
* @param session
* the session
* @param aggregateData
* aggregate data
* @param array
* values of expressions
*/
protected
abstract
void
updateFromExpressions
(
Session
session
,
Object
aggregateData
,
Value
[]
array
);
@Override
@Override
protected
void
updateAggregate
(
Session
session
,
SelectGroups
groupData
,
int
groupRowId
)
{
protected
void
updateAggregate
(
Session
session
,
SelectGroups
groupData
,
int
groupRowId
)
{
if
(
filterCondition
==
null
||
filterCondition
.
getBooleanValue
(
session
))
{
if
(
filterCondition
==
null
||
filterCondition
.
getBooleanValue
(
session
))
{
ArrayList
<
SelectOrderBy
>
orderBy
;
ArrayList
<
SelectOrderBy
>
orderBy
;
if
(
over
!=
null
&&
(
orderBy
=
over
.
getOrderBy
())
!=
null
)
{
if
(
over
!=
null
)
{
if
((
orderBy
=
over
.
getOrderBy
())
!=
null
)
{
updateOrderedAggregate
(
session
,
groupData
,
groupRowId
,
orderBy
);
updateOrderedAggregate
(
session
,
groupData
,
groupRowId
,
orderBy
);
}
else
{
}
else
{
updateAggregate
(
session
,
getData
(
session
,
groupData
,
false
,
false
));
updateAggregate
(
session
,
getWindowData
(
session
,
groupData
,
false
));
}
}
else
{
updateAggregate
(
session
,
getGroupData
(
groupData
,
false
));
}
}
}
}
}
}
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/expression/aggregate/AggregateDataHistogram.java
浏览文件 @
5b87daab
...
@@ -38,7 +38,7 @@ class AggregateDataHistogram extends AggregateData {
...
@@ -38,7 +38,7 @@ class AggregateDataHistogram extends AggregateData {
@Override
@Override
void
add
(
Database
database
,
int
dataType
,
Value
v
)
{
void
add
(
Database
database
,
int
dataType
,
Value
v
)
{
if
(
distinctValues
==
null
)
{
if
(
distinctValues
==
null
)
{
distinctValues
=
ValueHashMap
.
newInstance
();
distinctValues
=
new
ValueHashMap
<>
();
}
}
LongDataCounter
a
=
distinctValues
.
get
(
v
);
LongDataCounter
a
=
distinctValues
.
get
(
v
);
if
(
a
==
null
)
{
if
(
a
==
null
)
{
...
@@ -54,7 +54,7 @@ class AggregateDataHistogram extends AggregateData {
...
@@ -54,7 +54,7 @@ class AggregateDataHistogram extends AggregateData {
@Override
@Override
Value
getValue
(
Database
database
,
int
dataType
)
{
Value
getValue
(
Database
database
,
int
dataType
)
{
if
(
distinctValues
==
null
)
{
if
(
distinctValues
==
null
)
{
return
ValueArray
.
get
(
new
Value
[
0
]
).
convertTo
(
dataType
);
return
ValueArray
.
get
Empty
(
).
convertTo
(
dataType
);
}
}
ValueArray
[]
values
=
new
ValueArray
[
distinctValues
.
size
()];
ValueArray
[]
values
=
new
ValueArray
[
distinctValues
.
size
()];
int
i
=
0
;
int
i
=
0
;
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/expression/aggregate/AggregateDataMode.java
浏览文件 @
5b87daab
...
@@ -25,7 +25,7 @@ class AggregateDataMode extends AggregateData {
...
@@ -25,7 +25,7 @@ class AggregateDataMode extends AggregateData {
return
;
return
;
}
}
if
(
distinctValues
==
null
)
{
if
(
distinctValues
==
null
)
{
distinctValues
=
ValueHashMap
.
newInstance
();
distinctValues
=
new
ValueHashMap
<>
();
}
}
LongDataCounter
a
=
distinctValues
.
get
(
v
);
LongDataCounter
a
=
distinctValues
.
get
(
v
);
if
(
a
==
null
)
{
if
(
a
==
null
)
{
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/expression/aggregate/DataAnalysisOperation.java
浏览文件 @
5b87daab
...
@@ -8,7 +8,6 @@ package org.h2.expression.aggregate;
...
@@ -8,7 +8,6 @@ package org.h2.expression.aggregate;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.Collections
;
import
java.util.HashMap
;
import
java.util.HashMap
;
import
java.util.Iterator
;
import
org.h2.api.ErrorCode
;
import
org.h2.api.ErrorCode
;
import
org.h2.command.dml.Select
;
import
org.h2.command.dml.Select
;
...
@@ -21,9 +20,7 @@ import org.h2.message.DbException;
...
@@ -21,9 +20,7 @@ import org.h2.message.DbException;
import
org.h2.result.SortOrder
;
import
org.h2.result.SortOrder
;
import
org.h2.table.ColumnResolver
;
import
org.h2.table.ColumnResolver
;
import
org.h2.table.TableFilter
;
import
org.h2.table.TableFilter
;
import
org.h2.util.ValueHashMap
;
import
org.h2.value.Value
;
import
org.h2.value.Value
;
import
org.h2.value.ValueArray
;
import
org.h2.value.ValueInt
;
import
org.h2.value.ValueInt
;
/**
/**
...
@@ -184,64 +181,29 @@ public abstract class DataAnalysisOperation extends Expression {
...
@@ -184,64 +181,29 @@ public abstract class DataAnalysisOperation extends Expression {
*/
*/
protected
abstract
void
rememberExpressions
(
Session
session
,
Value
[]
array
);
protected
abstract
void
rememberExpressions
(
Session
session
,
Value
[]
array
);
/**
protected
Object
getWindowData
(
Session
session
,
SelectGroups
groupData
,
boolean
forOrderBy
)
{
* Updates the provided aggregate data from the remembered expressions.
*
* @param session
* the session
* @param aggregateData
* aggregate data
* @param array
* values of expressions
*/
protected
abstract
void
updateFromExpressions
(
Session
session
,
Object
aggregateData
,
Value
[]
array
);
protected
Object
getData
(
Session
session
,
SelectGroups
groupData
,
boolean
ifExists
,
boolean
forOrderBy
)
{
Object
data
;
Object
data
;
if
(
over
!=
null
)
{
Value
key
=
over
.
getCurrentKey
(
session
);
ValueArray
key
=
over
.
getCurrentKey
(
session
);
PartitionData
partition
=
groupData
.
getWindowExprData
(
this
,
key
);
if
(
key
!=
null
)
{
@SuppressWarnings
(
"unchecked"
)
ValueHashMap
<
Object
>
map
=
(
ValueHashMap
<
Object
>)
groupData
.
getWindowExprData
(
this
);
if
(
map
==
null
)
{
if
(
ifExists
)
{
return
null
;
}
map
=
new
ValueHashMap
<>();
groupData
.
setWindowExprData
(
this
,
map
);
}
PartitionData
partition
=
(
PartitionData
)
map
.
get
(
key
);
if
(
partition
==
null
)
{
if
(
partition
==
null
)
{
if
(
ifExists
)
{
return
null
;
}
data
=
forOrderBy
?
new
ArrayList
<>()
:
createAggregateData
();
data
=
forOrderBy
?
new
ArrayList
<>()
:
createAggregateData
();
map
.
put
(
key
,
new
PartitionData
(
data
));
groupData
.
setWindowExprData
(
this
,
key
,
new
PartitionData
(
data
));
}
else
{
data
=
partition
.
getData
();
}
}
else
{
PartitionData
partition
=
(
PartitionData
)
groupData
.
getWindowExprData
(
this
);
if
(
partition
==
null
)
{
if
(
ifExists
)
{
return
null
;
}
data
=
forOrderBy
?
new
ArrayList
<>()
:
createAggregateData
();
groupData
.
setWindowExprData
(
this
,
new
PartitionData
(
data
));
}
else
{
}
else
{
data
=
partition
.
getData
();
data
=
partition
.
getData
();
}
}
return
data
;
}
}
}
else
{
protected
Object
getGroupData
(
SelectGroups
groupData
,
boolean
ifExists
)
{
Object
data
;
data
=
groupData
.
getCurrentGroupExprData
(
this
);
data
=
groupData
.
getCurrentGroupExprData
(
this
);
if
(
data
==
null
)
{
if
(
data
==
null
)
{
if
(
ifExists
)
{
if
(
ifExists
)
{
return
null
;
return
null
;
}
}
data
=
forOrderBy
?
new
ArrayList
<>()
:
createAggregateData
();
data
=
createAggregateData
();
groupData
.
setCurrentGroupExprData
(
this
,
data
);
groupData
.
setCurrentGroupExprData
(
this
,
data
);
}
}
}
return
data
;
return
data
;
}
}
...
@@ -277,43 +239,38 @@ public abstract class DataAnalysisOperation extends Expression {
...
@@ -277,43 +239,38 @@ public abstract class DataAnalysisOperation extends Expression {
if
(
groupData
==
null
)
{
if
(
groupData
==
null
)
{
throw
DbException
.
get
(
ErrorCode
.
INVALID_USE_OF_AGGREGATE_FUNCTION_1
,
getSQL
());
throw
DbException
.
get
(
ErrorCode
.
INVALID_USE_OF_AGGREGATE_FUNCTION_1
,
getSQL
());
}
}
return
over
==
null
?
getAggregatedValue
(
session
,
get
Data
(
session
,
groupData
,
true
,
fals
e
))
return
over
==
null
?
getAggregatedValue
(
session
,
get
GroupData
(
groupData
,
tru
e
))
:
getWindowResult
(
session
,
groupData
);
:
getWindowResult
(
session
,
groupData
);
}
}
/**
* Returns result of this window function or window aggregate. This method
* is not used for plain aggregates.
*
* @param session
* the session
* @param groupData
* the group data
* @return result of this function
*/
private
Value
getWindowResult
(
Session
session
,
SelectGroups
groupData
)
{
private
Value
getWindowResult
(
Session
session
,
SelectGroups
groupData
)
{
PartitionData
partition
;
PartitionData
partition
;
Object
data
;
Object
data
;
boolean
forOrderBy
=
over
.
getOrderBy
()
!=
null
;
boolean
forOrderBy
=
over
.
getOrderBy
()
!=
null
;
ValueArray
key
=
over
.
getCurrentKey
(
session
);
Value
key
=
over
.
getCurrentKey
(
session
);
if
(
key
!=
null
)
{
partition
=
groupData
.
getWindowExprData
(
this
,
key
);
@SuppressWarnings
(
"unchecked"
)
ValueHashMap
<
Object
>
map
=
(
ValueHashMap
<
Object
>)
groupData
.
getWindowExprData
(
this
);
if
(
map
==
null
)
{
map
=
new
ValueHashMap
<>();
groupData
.
setWindowExprData
(
this
,
map
);
}
partition
=
(
PartitionData
)
map
.
get
(
key
);
if
(
partition
==
null
)
{
if
(
partition
==
null
)
{
// Window aggregates with FILTER clause may have no collected values
data
=
forOrderBy
?
new
ArrayList
<>()
:
createAggregateData
();
data
=
forOrderBy
?
new
ArrayList
<>()
:
createAggregateData
();
partition
=
new
PartitionData
(
data
);
partition
=
new
PartitionData
(
data
);
map
.
put
(
key
,
partition
);
groupData
.
setWindowExprData
(
this
,
key
,
partition
);
}
else
{
}
else
{
data
=
partition
.
getData
();
data
=
partition
.
getData
();
}
}
}
else
{
if
(
forOrderBy
||
!
isAggregate
())
{
partition
=
(
PartitionData
)
groupData
.
getWindowExprData
(
this
);
if
(
partition
==
null
)
{
data
=
forOrderBy
?
new
ArrayList
<>()
:
createAggregateData
();
partition
=
new
PartitionData
(
data
);
groupData
.
setWindowExprData
(
this
,
partition
);
}
else
{
data
=
partition
.
getData
();
}
}
if
(
over
.
getOrderBy
()
!=
null
||
!
isAggregate
())
{
return
getOrderedResult
(
session
,
groupData
,
partition
,
data
);
return
getOrderedResult
(
session
,
groupData
,
partition
,
data
);
}
}
// Window aggregate without ORDER BY clause in window specification
Value
result
=
partition
.
getResult
();
Value
result
=
partition
.
getResult
();
if
(
result
==
null
)
{
if
(
result
==
null
)
{
result
=
getAggregatedValue
(
session
,
data
);
result
=
getAggregatedValue
(
session
,
data
);
...
@@ -346,7 +303,7 @@ public abstract class DataAnalysisOperation extends Expression {
...
@@ -346,7 +303,7 @@ public abstract class DataAnalysisOperation extends Expression {
}
}
array
[
ne
]
=
ValueInt
.
get
(
groupRowId
);
array
[
ne
]
=
ValueInt
.
get
(
groupRowId
);
@SuppressWarnings
(
"unchecked"
)
@SuppressWarnings
(
"unchecked"
)
ArrayList
<
Value
[]>
data
=
(
ArrayList
<
Value
[]>)
get
Data
(
session
,
groupData
,
false
,
true
);
ArrayList
<
Value
[]>
data
=
(
ArrayList
<
Value
[]>)
get
WindowData
(
session
,
groupData
,
true
);
data
.
add
(
array
);
data
.
add
(
array
);
}
}
...
@@ -378,36 +335,8 @@ public abstract class DataAnalysisOperation extends Expression {
...
@@ -378,36 +335,8 @@ public abstract class DataAnalysisOperation extends Expression {
* @param rowIdColumn
* @param rowIdColumn
* the index of row id value
* the index of row id value
*/
*/
protected
void
getOrderedResultLoop
(
Session
session
,
HashMap
<
Integer
,
Value
>
result
,
ArrayList
<
Value
[]>
ordered
,
protected
abstract
void
getOrderedResultLoop
(
Session
session
,
HashMap
<
Integer
,
Value
>
result
,
int
rowIdColumn
)
{
ArrayList
<
Value
[]>
ordered
,
int
rowIdColumn
);
WindowFrame
frame
=
over
.
getWindowFrame
();
if
(
frame
==
null
||
frame
.
isDefault
())
{
Object
aggregateData
=
createAggregateData
();
for
(
Value
[]
row
:
ordered
)
{
updateFromExpressions
(
session
,
aggregateData
,
row
);
result
.
put
(
row
[
rowIdColumn
].
getInt
(),
getAggregatedValue
(
session
,
aggregateData
));
}
}
else
if
(
frame
.
isFullPartition
())
{
Object
aggregateData
=
createAggregateData
();
for
(
Value
[]
row
:
ordered
)
{
updateFromExpressions
(
session
,
aggregateData
,
row
);
}
Value
value
=
getAggregatedValue
(
session
,
aggregateData
);
for
(
Value
[]
row
:
ordered
)
{
result
.
put
(
row
[
rowIdColumn
].
getInt
(),
value
);
}
}
else
{
int
size
=
ordered
.
size
();
for
(
int
i
=
0
;
i
<
size
;
i
++)
{
Object
aggregateData
=
createAggregateData
();
for
(
Iterator
<
Value
[]>
iter
=
frame
.
iterator
(
session
,
ordered
,
getOverOrderBySort
(),
i
,
false
);
iter
.
hasNext
();)
{
updateFromExpressions
(
session
,
aggregateData
,
iter
.
next
());
}
result
.
put
(
ordered
.
get
(
i
)[
rowIdColumn
].
getInt
(),
getAggregatedValue
(
session
,
aggregateData
));
}
}
}
protected
StringBuilder
appendTailConditions
(
StringBuilder
builder
)
{
protected
StringBuilder
appendTailConditions
(
StringBuilder
builder
)
{
if
(
over
!=
null
)
{
if
(
over
!=
null
)
{
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/expression/aggregate/PartitionData.java
浏览文件 @
5b87daab
...
@@ -12,7 +12,7 @@ import org.h2.value.Value;
...
@@ -12,7 +12,7 @@ import org.h2.value.Value;
/**
/**
* Partition data of a window aggregate.
* Partition data of a window aggregate.
*/
*/
final
class
PartitionData
{
public
final
class
PartitionData
{
/**
/**
* Aggregate data.
* Aggregate data.
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/expression/aggregate/Window.java
浏览文件 @
5b87daab
...
@@ -185,11 +185,14 @@ public final class Window {
...
@@ -185,11 +185,14 @@ public final class Window {
* session
* session
* @return key for the current group, or null
* @return key for the current group, or null
*/
*/
public
Value
Array
getCurrentKey
(
Session
session
)
{
public
Value
getCurrentKey
(
Session
session
)
{
if
(
partitionBy
==
null
)
{
if
(
partitionBy
==
null
)
{
return
null
;
return
null
;
}
}
int
len
=
partitionBy
.
size
();
int
len
=
partitionBy
.
size
();
if
(
len
==
1
)
{
return
partitionBy
.
get
(
0
).
getValue
(
session
);
}
else
{
Value
[]
keyValues
=
new
Value
[
len
];
Value
[]
keyValues
=
new
Value
[
len
];
// update group
// update group
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
...
@@ -198,6 +201,7 @@ public final class Window {
...
@@ -198,6 +201,7 @@ public final class Window {
}
}
return
ValueArray
.
get
(
keyValues
);
return
ValueArray
.
get
(
keyValues
);
}
}
}
/**
/**
* Returns SQL representation.
* Returns SQL representation.
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/expression/aggregate/WindowFunction.java
浏览文件 @
5b87daab
...
@@ -174,11 +174,6 @@ public class WindowFunction extends DataAnalysisOperation {
...
@@ -174,11 +174,6 @@ public class WindowFunction extends DataAnalysisOperation {
}
}
}
}
@Override
protected
void
updateFromExpressions
(
Session
session
,
Object
aggregateData
,
Value
[]
array
)
{
throw
DbException
.
getUnsupportedException
(
"Window function"
);
}
@Override
@Override
protected
Object
createAggregateData
()
{
protected
Object
createAggregateData
()
{
throw
DbException
.
getUnsupportedException
(
"Window function"
);
throw
DbException
.
getUnsupportedException
(
"Window function"
);
...
@@ -188,62 +183,58 @@ public class WindowFunction extends DataAnalysisOperation {
...
@@ -188,62 +183,58 @@ public class WindowFunction extends DataAnalysisOperation {
protected
void
getOrderedResultLoop
(
Session
session
,
HashMap
<
Integer
,
Value
>
result
,
ArrayList
<
Value
[]>
ordered
,
protected
void
getOrderedResultLoop
(
Session
session
,
HashMap
<
Integer
,
Value
>
result
,
ArrayList
<
Value
[]>
ordered
,
int
rowIdColumn
)
{
int
rowIdColumn
)
{
switch
(
type
)
{
switch
(
type
)
{
case
ROW_NUMBER:
for
(
int
i
=
0
,
size
=
ordered
.
size
();
i
<
size
;)
{
result
.
put
(
ordered
.
get
(
i
)[
rowIdColumn
].
getInt
(),
ValueInt
.
get
(++
i
));
}
break
;
case
RANK:
case
DENSE_RANK:
case
PERCENT_RANK:
getRank
(
result
,
ordered
,
rowIdColumn
);
break
;
case
CUME_DIST:
case
CUME_DIST:
getCumeDist
(
session
,
result
,
ordered
,
rowIdColumn
);
getCumeDist
(
session
,
result
,
ordered
,
rowIdColumn
);
return
;
break
;
case
NTILE:
case
NTILE:
getNtile
(
session
,
result
,
ordered
,
rowIdColumn
);
getNtile
(
session
,
result
,
ordered
,
rowIdColumn
);
return
;
break
;
case
LEAD:
case
LEAD:
case
LAG:
case
LAG:
getLeadLag
(
session
,
result
,
ordered
,
rowIdColumn
);
getLeadLag
(
session
,
result
,
ordered
,
rowIdColumn
);
return
;
break
;
case
FIRST_VALUE:
case
FIRST_VALUE:
case
LAST_VALUE:
case
LAST_VALUE:
case
NTH_VALUE:
case
NTH_VALUE:
getNth
(
session
,
result
,
ordered
,
rowIdColumn
);
getNth
(
session
,
result
,
ordered
,
rowIdColumn
);
return
;
break
;
default
:
default
:
throw
DbException
.
throwInternalError
(
"type="
+
type
);
}
}
}
private
void
getRank
(
HashMap
<
Integer
,
Value
>
result
,
ArrayList
<
Value
[]>
ordered
,
int
rowIdColumn
)
{
int
size
=
ordered
.
size
();
int
size
=
ordered
.
size
();
int
number
=
0
;
int
number
=
0
;
for
(
int
i
=
0
;
i
<
size
;
i
++)
{
for
(
int
i
=
0
;
i
<
size
;
i
++)
{
Value
[]
row
=
ordered
.
get
(
i
);
Value
[]
row
=
ordered
.
get
(
i
);
int
rowId
=
row
[
rowIdColumn
].
getInt
();
Value
v
;
switch
(
type
)
{
case
ROW_NUMBER:
v
=
ValueInt
.
get
(
i
+
1
);
break
;
case
RANK:
case
DENSE_RANK:
case
PERCENT_RANK:
{
if
(
i
==
0
)
{
if
(
i
==
0
)
{
number
=
1
;
number
=
1
;
}
else
if
(
getOverOrderBySort
().
compare
(
ordered
.
get
(
i
-
1
),
row
)
!=
0
)
{
if
(
type
==
WindowFunctionType
.
DENSE_RANK
)
{
number
++;
}
else
{
}
else
{
if
(
getOverOrderBySort
().
compare
(
ordered
.
get
(
i
-
1
),
row
)
!=
0
)
{
switch
(
type
)
{
case
RANK:
case
PERCENT_RANK:
number
=
i
+
1
;
number
=
i
+
1
;
break
;
default
:
// DENSE_RANK
number
++;
}
}
}
}
}
Value
v
;
if
(
type
==
WindowFunctionType
.
PERCENT_RANK
)
{
if
(
type
==
WindowFunctionType
.
PERCENT_RANK
)
{
int
nm
=
number
-
1
;
int
nm
=
number
-
1
;
v
=
nm
==
0
?
ValueDouble
.
ZERO
:
ValueDouble
.
get
((
double
)
nm
/
(
size
-
1
));
v
=
nm
==
0
?
ValueDouble
.
ZERO
:
ValueDouble
.
get
((
double
)
nm
/
(
size
-
1
));
}
else
{
}
else
{
v
=
ValueInt
.
get
(
number
);
v
=
ValueInt
.
get
(
number
);
}
}
break
;
result
.
put
(
row
[
rowIdColumn
].
getInt
(),
v
);
}
default
:
throw
DbException
.
throwInternalError
(
"type="
+
type
);
}
result
.
put
(
rowId
,
v
);
}
}
}
}
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/index/HashIndex.java
浏览文件 @
5b87daab
...
@@ -40,7 +40,7 @@ public class HashIndex extends BaseIndex {
...
@@ -40,7 +40,7 @@ public class HashIndex extends BaseIndex {
}
}
private
void
reset
()
{
private
void
reset
()
{
rows
=
ValueHashMap
.
newInstance
();
rows
=
new
ValueHashMap
<>
();
}
}
@Override
@Override
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/index/NonUniqueHashIndex.java
浏览文件 @
5b87daab
...
@@ -45,7 +45,7 @@ public class NonUniqueHashIndex extends BaseIndex {
...
@@ -45,7 +45,7 @@ public class NonUniqueHashIndex extends BaseIndex {
}
}
private
void
reset
()
{
private
void
reset
()
{
rows
=
ValueHashMap
.
newInstance
();
rows
=
new
ValueHashMap
<>
();
rowCount
=
0
;
rowCount
=
0
;
}
}
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/result/LocalResultImpl.java
浏览文件 @
5b87daab
...
@@ -147,7 +147,7 @@ public class LocalResultImpl implements LocalResult {
...
@@ -147,7 +147,7 @@ public class LocalResultImpl implements LocalResult {
public
void
setDistinct
()
{
public
void
setDistinct
()
{
assert
distinctIndexes
==
null
;
assert
distinctIndexes
==
null
;
distinct
=
true
;
distinct
=
true
;
distinctRows
=
ValueHashMap
.
newInstance
();
distinctRows
=
new
ValueHashMap
<>
();
}
}
/**
/**
...
@@ -159,7 +159,7 @@ public class LocalResultImpl implements LocalResult {
...
@@ -159,7 +159,7 @@ public class LocalResultImpl implements LocalResult {
public
void
setDistinct
(
int
[]
distinctIndexes
)
{
public
void
setDistinct
(
int
[]
distinctIndexes
)
{
assert
!
distinct
;
assert
!
distinct
;
this
.
distinctIndexes
=
distinctIndexes
;
this
.
distinctIndexes
=
distinctIndexes
;
distinctRows
=
ValueHashMap
.
newInstance
();
distinctRows
=
new
ValueHashMap
<>
();
}
}
/**
/**
...
@@ -202,7 +202,7 @@ public class LocalResultImpl implements LocalResult {
...
@@ -202,7 +202,7 @@ public class LocalResultImpl implements LocalResult {
return
external
.
contains
(
values
);
return
external
.
contains
(
values
);
}
}
if
(
distinctRows
==
null
)
{
if
(
distinctRows
==
null
)
{
distinctRows
=
ValueHashMap
.
newInstance
();
distinctRows
=
new
ValueHashMap
<>
();
for
(
Value
[]
row
:
rows
)
{
for
(
Value
[]
row
:
rows
)
{
ValueArray
array
=
getArrayOfDistinct
(
row
);
ValueArray
array
=
getArrayOfDistinct
(
row
);
distinctRows
.
put
(
array
,
array
.
getList
());
distinctRows
.
put
(
array
,
array
.
getList
());
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/util/ValueHashMap.java
浏览文件 @
5b87daab
...
@@ -38,15 +38,6 @@ public class ValueHashMap<V> extends HashBase {
...
@@ -38,15 +38,6 @@ public class ValueHashMap<V> extends HashBase {
Value
[]
keys
;
Value
[]
keys
;
V
[]
values
;
V
[]
values
;
/**
* Create a new value hash map.
*
* @return the object
*/
public
static
<
T
>
ValueHashMap
<
T
>
newInstance
()
{
return
new
ValueHashMap
<>();
}
@Override
@Override
@SuppressWarnings
(
"unchecked"
)
@SuppressWarnings
(
"unchecked"
)
protected
void
reset
(
int
newLevel
)
{
protected
void
reset
(
int
newLevel
)
{
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/value/ValueArray.java
浏览文件 @
5b87daab
...
@@ -20,6 +20,11 @@ import org.h2.util.StatementBuilder;
...
@@ -20,6 +20,11 @@ import org.h2.util.StatementBuilder;
*/
*/
public
class
ValueArray
extends
Value
{
public
class
ValueArray
extends
Value
{
/**
* Empty array.
*/
private
static
final
Object
EMPTY
=
get
(
new
Value
[
0
]);
private
final
Class
<?>
componentType
;
private
final
Class
<?>
componentType
;
private
final
Value
[]
values
;
private
final
Value
[]
values
;
private
int
hash
;
private
int
hash
;
...
@@ -52,6 +57,15 @@ public class ValueArray extends Value {
...
@@ -52,6 +57,15 @@ public class ValueArray extends Value {
return
new
ValueArray
(
componentType
,
list
);
return
new
ValueArray
(
componentType
,
list
);
}
}
/**
* Returns empty array.
*
* @return empty array
*/
public
static
ValueArray
getEmpty
()
{
return
(
ValueArray
)
EMPTY
;
}
@Override
@Override
public
int
hashCode
()
{
public
int
hashCode
()
{
if
(
hash
!=
0
)
{
if
(
hash
!=
0
)
{
...
...
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/scripts/functions/aggregate/count.sql
浏览文件 @
5b87daab
...
@@ -83,3 +83,14 @@ SELECT I, V, COUNT(V) OVER W C, COUNT(DISTINCT V) OVER W D FROM
...
@@ -83,3 +83,14 @@ SELECT I, V, COUNT(V) OVER W C, COUNT(DISTINCT V) OVER W D FROM
>
6
2
6
2
>
6
2
6
2
>
7
3
7
3
>
7
3
7
3
>
rows
(
ordered
):
7
>
rows
(
ordered
):
7
SELECT
I
,
C
,
COUNT
(
I
)
OVER
(
PARTITION
BY
C
)
CNT
FROM
VALUES
(
1
,
1
),
(
2
,
1
),
(
3
,
2
),
(
4
,
2
),
(
5
,
2
)
T
(
I
,
C
);
>
I
C
CNT
>
-
-
---
>
1
1
2
>
2
1
2
>
3
2
3
>
4
2
3
>
5
2
3
>
rows
:
5
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/scripts/functions/window/lead.sql
浏览文件 @
5b87daab
...
@@ -143,3 +143,11 @@ SELECT LAG(VALUE) OVER (ORDER BY ID RANGE CURRENT ROW) FROM TEST;
...
@@ -143,3 +143,11 @@ SELECT LAG(VALUE) OVER (ORDER BY ID RANGE CURRENT ROW) FROM TEST;
DROP
TABLE
TEST
;
DROP
TABLE
TEST
;
>
ok
>
ok
SELECT
C
,
SUM
(
I
)
S
,
LEAD
(
SUM
(
I
))
OVER
(
ORDER
/**/
BY
SUM
(
I
))
L
FROM
VALUES
(
1
,
1
),
(
2
,
1
),
(
4
,
2
),
(
8
,
2
)
T
(
I
,
C
)
GROUP
BY
C
;
>
C
S
L
>
-
-- ----
>
1
3
12
>
2
12
null
>
rows
:
2
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/scripts/functions/window/row_number.sql
浏览文件 @
5b87daab
...
@@ -133,7 +133,7 @@ INSERT INTO TEST VALUES
...
@@ -133,7 +133,7 @@ INSERT INTO TEST VALUES
(
4
,
'b'
,
8
);
(
4
,
'b'
,
8
);
>
update
count
:
4
>
update
count
:
4
SELECT
ROW_NUMBER
()
OVER
(
ORDER
/**/
BY
TYPE
)
RN
,
TYPE
,
SUM
(
CNT
)
SUM
FROM
TEST
GROUP
BY
TYPE
;
SELECT
ROW_NUMBER
()
OVER
(
ORDER
/**/
BY
TYPE
)
RN
,
TYPE
,
SUM
(
CNT
)
SUM
FROM
TEST
GROUP
BY
TYPE
;
>
RN
TYPE
SUM
>
RN
TYPE
SUM
>
-- ---- ---
>
-- ---- ---
>
1
a
1
>
1
a
1
...
@@ -141,6 +141,16 @@ SELECT ROW_NUMBER() OVER(ORDER /**/ BY TYPE) RN, TYPE, SUM(CNT) SUM FROM TEST GR
...
@@ -141,6 +141,16 @@ SELECT ROW_NUMBER() OVER(ORDER /**/ BY TYPE) RN, TYPE, SUM(CNT) SUM FROM TEST GR
>
3
c
4
>
3
c
4
>
rows
:
3
>
rows
:
3
SELECT
A
,
B
,
C
,
ROW_NUMBER
()
OVER
(
PARTITION
BY
A
,
B
)
N
FROM
VALUES
(
1
,
1
,
1
),
(
1
,
1
,
2
),
(
1
,
2
,
3
),
(
2
,
1
,
4
)
T
(
A
,
B
,
C
);
>
A
B
C
N
>
-
-
-
-
>
1
1
1
1
>
1
1
2
2
>
1
2
3
1
>
2
1
4
1
>
rows
:
4
SELECT
RANK
()
OVER
()
FROM
TEST
;
SELECT
RANK
()
OVER
()
FROM
TEST
;
>
exception
SYNTAX_ERROR_2
>
exception
SYNTAX_ERROR_2
...
@@ -149,3 +159,9 @@ SELECT DENSE_RANK () OVER () FROM TEST;
...
@@ -149,3 +159,9 @@ SELECT DENSE_RANK () OVER () FROM TEST;
DROP
TABLE
TEST
;
DROP
TABLE
TEST
;
>
ok
>
ok
SELECT
ROW_NUMBER
()
OVER
()
FROM
VALUES
(
1
);
>
ROW_NUMBER
()
OVER
()
>
--------------------
>
1
>
rows
:
1
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/unit/TestValueHashMap.java
浏览文件 @
5b87daab
...
@@ -47,7 +47,7 @@ public class TestValueHashMap extends TestBase implements DataHandler {
...
@@ -47,7 +47,7 @@ public class TestValueHashMap extends TestBase implements DataHandler {
}
}
private
void
testNotANumber
()
{
private
void
testNotANumber
()
{
ValueHashMap
<
Integer
>
map
=
ValueHashMap
.
newInstance
();
ValueHashMap
<
Integer
>
map
=
new
ValueHashMap
<>
();
for
(
int
i
=
1
;
i
<
100
;
i
++)
{
for
(
int
i
=
1
;
i
<
100
;
i
++)
{
double
d
=
Double
.
longBitsToDouble
(
0x7ff0000000000000
L
|
i
);
double
d
=
Double
.
longBitsToDouble
(
0x7ff0000000000000
L
|
i
);
ValueDouble
v
=
ValueDouble
.
get
(
d
);
ValueDouble
v
=
ValueDouble
.
get
(
d
);
...
@@ -57,7 +57,7 @@ public class TestValueHashMap extends TestBase implements DataHandler {
...
@@ -57,7 +57,7 @@ public class TestValueHashMap extends TestBase implements DataHandler {
}
}
private
void
testRandomized
()
{
private
void
testRandomized
()
{
ValueHashMap
<
Value
>
map
=
ValueHashMap
.
newInstance
();
ValueHashMap
<
Value
>
map
=
new
ValueHashMap
<>
();
HashMap
<
Value
,
Value
>
hash
=
new
HashMap
<>();
HashMap
<
Value
,
Value
>
hash
=
new
HashMap
<>();
Random
random
=
new
Random
(
1
);
Random
random
=
new
Random
(
1
);
Comparator
<
Value
>
vc
=
new
Comparator
<
Value
>()
{
Comparator
<
Value
>
vc
=
new
Comparator
<
Value
>()
{
...
...
This diff is collapsed.
Click to expand it.
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论