Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
6547ef35
提交
6547ef35
authored
1月 19, 2019
作者:
Evgenij Ryazanov
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Remove unused ValueHashMap
上级
52b412bd
隐藏空白字符变更
内嵌
并排
正在显示
3 个修改的文件
包含
0 行增加
和
467 行删除
+0
-467
ValueHashMap.java
h2/src/main/org/h2/util/ValueHashMap.java
+0
-284
TestAll.java
h2/src/test/org/h2/test/TestAll.java
+0
-2
TestValueHashMap.java
h2/src/test/org/h2/test/unit/TestValueHashMap.java
+0
-181
没有找到文件。
h2/src/main/org/h2/util/ValueHashMap.java
deleted
100644 → 0
浏览文件 @
52b412bd
/*
* Copyright 2004-2019 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
util
;
import
java.util.AbstractMap
;
import
java.util.ArrayList
;
import
java.util.Iterator
;
import
java.util.Map
;
import
java.util.NoSuchElementException
;
import
org.h2.message.DbException
;
import
org.h2.value.Value
;
import
org.h2.value.ValueNull
;
/**
* This hash map supports keys of type Value.
* <p>
* ValueHashMap is a very simple implementation without allocation of additional
* objects for entries. It's very fast with good distribution of hashes, but if
* hashes have a lot of collisions this implementation tends to be very slow.
* <p>
* HashMap in archaic versions of Java have some overhead for allocation of
* entries, but slightly better behaviour with limited number of collisions,
* because collisions have no impact on non-colliding entries. HashMap in modern
* versions of Java also have the same overhead, but it builds a trees of keys
* with colliding hashes, that's why even if the all keys have exactly the same
* hash code it still offers a good performance similar to TreeMap. So
* ValueHashMap is faster in typical cases, but may behave really bad in some
* cases. HashMap is slower in typical cases, but its performance does not
* degrade too much even in the worst possible case (if keys are comparable).
*
* @param <V> the value type
*/
public
class
ValueHashMap
<
V
>
extends
HashBase
{
/**
* Keys array.
*/
Value
[]
keys
;
/**
* Values array.
*/
V
[]
values
;
@Override
@SuppressWarnings
(
"unchecked"
)
protected
void
reset
(
int
newLevel
)
{
super
.
reset
(
newLevel
);
keys
=
new
Value
[
len
];
values
=
(
V
[])
new
Object
[
len
];
}
@Override
protected
void
rehash
(
int
newLevel
)
{
Value
[]
oldKeys
=
keys
;
V
[]
oldValues
=
values
;
reset
(
newLevel
);
int
len
=
oldKeys
.
length
;
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
Value
k
=
oldKeys
[
i
];
if
(
k
!=
null
&&
k
!=
ValueNull
.
DELETED
)
{
// skip the checkSizePut so we don't end up
// accidentally recursing
internalPut
(
k
,
oldValues
[
i
],
false
);
}
}
}
private
int
getIndex
(
Value
key
)
{
int
h
=
key
.
hashCode
();
/*
* Add some protection against hashes with the same less significant bits
* (ValueDouble with integer values, for example).
*/
return
(
h
^
h
>>>
16
)
&
mask
;
}
/**
* Add or update a key value pair.
*
* @param key the key
* @param value the new value
*/
public
void
put
(
Value
key
,
V
value
)
{
checkSizePut
();
internalPut
(
key
,
value
,
false
);
}
/**
* Add a key value pair, values for existing keys are not replaced.
*
* @param key the key
* @param value the new value
*/
public
void
putIfAbsent
(
Value
key
,
V
value
)
{
checkSizePut
();
internalPut
(
key
,
value
,
true
);
}
private
void
internalPut
(
Value
key
,
V
value
,
boolean
ifAbsent
)
{
int
index
=
getIndex
(
key
);
int
plus
=
1
;
int
deleted
=
-
1
;
do
{
Value
k
=
keys
[
index
];
if
(
k
==
null
)
{
// found an empty record
if
(
deleted
>=
0
)
{
index
=
deleted
;
deletedCount
--;
}
size
++;
keys
[
index
]
=
key
;
values
[
index
]
=
value
;
return
;
}
else
if
(
k
==
ValueNull
.
DELETED
)
{
// found a deleted record
if
(
deleted
<
0
)
{
deleted
=
index
;
}
}
else
if
(
k
.
equals
(
key
))
{
if
(
ifAbsent
)
{
return
;
}
// update existing
values
[
index
]
=
value
;
return
;
}
index
=
(
index
+
plus
++)
&
mask
;
}
while
(
plus
<=
len
);
// no space
DbException
.
throwInternalError
(
"hashmap is full"
);
}
/**
* Remove a key value pair.
*
* @param key the key
*/
public
void
remove
(
Value
key
)
{
checkSizeRemove
();
int
index
=
getIndex
(
key
);
int
plus
=
1
;
do
{
Value
k
=
keys
[
index
];
if
(
k
==
null
)
{
// found an empty record
return
;
}
else
if
(
k
==
ValueNull
.
DELETED
)
{
// found a deleted record
}
else
if
(
k
.
equals
(
key
))
{
// found the record
keys
[
index
]
=
ValueNull
.
DELETED
;
values
[
index
]
=
null
;
deletedCount
++;
size
--;
return
;
}
index
=
(
index
+
plus
++)
&
mask
;
}
while
(
plus
<=
len
);
// not found
}
/**
* Get the value for this key. This method returns null if the key was not
* found.
*
* @param key the key
* @return the value for the given key
*/
public
V
get
(
Value
key
)
{
int
index
=
getIndex
(
key
);
int
plus
=
1
;
do
{
Value
k
=
keys
[
index
];
if
(
k
==
null
)
{
// found an empty record
return
null
;
}
else
if
(
k
==
ValueNull
.
DELETED
)
{
// found a deleted record
}
else
if
(
k
.
equals
(
key
))
{
// found it
return
values
[
index
];
}
index
=
(
index
+
plus
++)
&
mask
;
}
while
(
plus
<=
len
);
return
null
;
}
/**
* Get the keys.
*
* @return all keys
*/
public
Iterable
<
Value
>
keys
()
{
return
new
KeyIterable
();
}
private
final
class
KeyIterable
implements
Iterable
<
Value
>
{
KeyIterable
()
{
}
@Override
public
Iterator
<
Value
>
iterator
()
{
return
new
UnifiedIterator
<>(
false
);
}
}
/**
* Gets all map's entries.
*
* @return all map's entries.
*/
public
Iterable
<
Map
.
Entry
<
Value
,
V
>>
entries
()
{
return
new
EntryIterable
();
}
private
final
class
EntryIterable
implements
Iterable
<
Map
.
Entry
<
Value
,
V
>>
{
EntryIterable
()
{
}
@Override
public
Iterator
<
Map
.
Entry
<
Value
,
V
>>
iterator
()
{
return
new
UnifiedIterator
<>(
true
);
}
}
final
class
UnifiedIterator
<
T
>
implements
Iterator
<
T
>
{
int
keysIndex
=
-
1
;
int
left
=
size
;
private
final
boolean
forEntries
;
UnifiedIterator
(
boolean
forEntries
)
{
this
.
forEntries
=
forEntries
;
}
@Override
public
boolean
hasNext
()
{
return
left
>
0
;
}
@SuppressWarnings
(
"unchecked"
)
@Override
public
T
next
()
{
if
(
left
<=
0
)
throw
new
NoSuchElementException
();
left
--;
for
(;;)
{
keysIndex
++;
Value
key
=
keys
[
keysIndex
];
if
(
key
!=
null
&&
key
!=
ValueNull
.
DELETED
)
{
return
(
T
)
(
forEntries
?
new
AbstractMap
.
SimpleImmutableEntry
<>(
key
,
values
[
keysIndex
])
:
key
);
}
}
}
@Override
public
void
remove
()
{
throw
new
UnsupportedOperationException
();
}
}
/**
* Get the list of values.
*
* @return all values
*/
public
ArrayList
<
V
>
values
()
{
ArrayList
<
V
>
list
=
new
ArrayList
<>(
size
);
int
len
=
keys
.
length
;
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
Value
k
=
keys
[
i
];
if
(
k
!=
null
&&
k
!=
ValueNull
.
DELETED
)
{
list
.
add
(
values
[
i
]);
}
}
return
list
;
}
}
h2/src/test/org/h2/test/TestAll.java
浏览文件 @
6547ef35
...
...
@@ -229,7 +229,6 @@ import org.h2.test.unit.TestTools;
import
org.h2.test.unit.TestTraceSystem
;
import
org.h2.test.unit.TestUtils
;
import
org.h2.test.unit.TestValue
;
import
org.h2.test.unit.TestValueHashMap
;
import
org.h2.test.unit.TestValueMemory
;
import
org.h2.test.utils.OutputCatcher
;
import
org.h2.test.utils.SelfDestructor
;
...
...
@@ -994,7 +993,6 @@ kill -9 `jps -l | grep "org.h2.test." | cut -d " " -f 1`
addTest
(
new
TestStringUtils
());
addTest
(
new
TestTraceSystem
());
addTest
(
new
TestUtils
());
addTest
(
new
TestValueHashMap
());
addTest
(
new
TestLocalResultFactory
());
runAddedTests
();
...
...
h2/src/test/org/h2/test/unit/TestValueHashMap.java
deleted
100644 → 0
浏览文件 @
52b412bd
/*
* Copyright 2004-2019 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
test
.
unit
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.Comparator
;
import
java.util.HashMap
;
import
java.util.Random
;
import
org.h2.api.JavaObjectSerializer
;
import
org.h2.store.DataHandler
;
import
org.h2.store.FileStore
;
import
org.h2.store.LobStorageBackend
;
import
org.h2.test.TestBase
;
import
org.h2.util.SmallLRUCache
;
import
org.h2.util.TempFileDeleter
;
import
org.h2.util.ValueHashMap
;
import
org.h2.value.CompareMode
;
import
org.h2.value.Value
;
import
org.h2.value.ValueDouble
;
import
org.h2.value.ValueInt
;
/**
* Tests the value hash map.
*/
public
class
TestValueHashMap
extends
TestBase
implements
DataHandler
{
CompareMode
compareMode
=
CompareMode
.
getInstance
(
null
,
0
);
/**
* Run just this test.
*
* @param a ignored
*/
public
static
void
main
(
String
...
a
)
throws
Exception
{
TestBase
.
createCaller
().
init
().
test
();
}
@Override
public
void
test
()
{
testNotANumber
();
testRandomized
();
}
private
void
testNotANumber
()
{
ValueHashMap
<
Integer
>
map
=
new
ValueHashMap
<>();
for
(
int
i
=
1
;
i
<
100
;
i
++)
{
double
d
=
Double
.
longBitsToDouble
(
0x7ff0000000000000
L
|
i
);
ValueDouble
v
=
ValueDouble
.
get
(
d
);
map
.
put
(
v
,
null
);
assertEquals
(
1
,
map
.
size
());
}
}
private
void
testRandomized
()
{
ValueHashMap
<
Value
>
map
=
new
ValueHashMap
<>();
HashMap
<
Value
,
Value
>
hash
=
new
HashMap
<>();
Random
random
=
new
Random
(
1
);
Comparator
<
Value
>
vc
=
new
Comparator
<
Value
>()
{
@Override
public
int
compare
(
Value
v1
,
Value
v2
)
{
return
v1
.
compareTo
(
v2
,
null
,
compareMode
);
}
};
for
(
int
i
=
0
;
i
<
10000
;
i
++)
{
int
op
=
random
.
nextInt
(
10
);
Value
key
=
ValueInt
.
get
(
random
.
nextInt
(
100
));
Value
value
=
ValueInt
.
get
(
random
.
nextInt
(
100
));
switch
(
op
)
{
case
0
:
map
.
put
(
key
,
value
);
hash
.
put
(
key
,
value
);
break
;
case
1
:
map
.
remove
(
key
);
hash
.
remove
(
key
);
break
;
case
2
:
Value
v1
=
map
.
get
(
key
);
Value
v2
=
hash
.
get
(
key
);
assertTrue
(
v1
==
null
?
v2
==
null
:
v1
.
equals
(
v2
));
break
;
case
3
:
{
ArrayList
<
Value
>
a1
=
new
ArrayList
<>();
for
(
Value
v
:
map
.
keys
())
{
a1
.
add
(
v
);
}
ArrayList
<
Value
>
a2
=
new
ArrayList
<>(
hash
.
keySet
());
assertEquals
(
a1
.
size
(),
a2
.
size
());
Collections
.
sort
(
a1
,
vc
);
Collections
.
sort
(
a2
,
vc
);
for
(
int
j
=
0
;
j
<
a1
.
size
();
j
++)
{
assertTrue
(
a1
.
get
(
j
).
equals
(
a2
.
get
(
j
)));
}
break
;
}
case
4
:
ArrayList
<
Value
>
a1
=
map
.
values
();
ArrayList
<
Value
>
a2
=
new
ArrayList
<>(
hash
.
values
());
assertEquals
(
a1
.
size
(),
a2
.
size
());
Collections
.
sort
(
a1
,
vc
);
Collections
.
sort
(
a2
,
vc
);
for
(
int
j
=
0
;
j
<
a1
.
size
();
j
++)
{
assertTrue
(
a1
.
get
(
j
).
equals
(
a2
.
get
(
j
)));
}
break
;
default
:
}
}
}
@Override
public
String
getDatabasePath
()
{
return
null
;
}
@Override
public
FileStore
openFile
(
String
name
,
String
mode
,
boolean
mustExist
)
{
return
null
;
}
@Override
public
void
checkPowerOff
()
{
// nothing to do
}
@Override
public
void
checkWritingAllowed
()
{
// nothing to do
}
@Override
public
int
getMaxLengthInplaceLob
()
{
return
0
;
}
@Override
public
String
getLobCompressionAlgorithm
(
int
type
)
{
return
null
;
}
@Override
public
Object
getLobSyncObject
()
{
return
this
;
}
@Override
public
SmallLRUCache
<
String
,
String
[]>
getLobFileListCache
()
{
return
null
;
}
@Override
public
TempFileDeleter
getTempFileDeleter
()
{
return
TempFileDeleter
.
getInstance
();
}
@Override
public
LobStorageBackend
getLobStorage
()
{
return
null
;
}
@Override
public
int
readLob
(
long
lobId
,
byte
[]
hmac
,
long
offset
,
byte
[]
buff
,
int
off
,
int
length
)
{
return
-
1
;
}
@Override
public
JavaObjectSerializer
getJavaObjectSerializer
()
{
return
null
;
}
@Override
public
CompareMode
getCompareMode
()
{
return
compareMode
;
}
}
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论