Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
6547ef35
提交
6547ef35
authored
6 年前
作者:
Evgenij Ryazanov
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Remove unused ValueHashMap
上级
52b412bd
master
version-1.4.198
无相关合并请求
隐藏空白字符变更
内嵌
并排
正在显示
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
;
}
}
This diff is collapsed.
Click to expand it.
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
();
...
...
This diff is collapsed.
Click to expand it.
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
;
}
}
This diff is collapsed.
Click to expand it.
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论