Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
82b73a05
提交
82b73a05
authored
11 年前
作者:
Thomas Mueller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
A concurrent linked list, to replace the array list of old roots (work in progress)
上级
09d4c1c4
master
noel-pr1
plus33-master
pr/267
stumc-Issue#576
version-1.4.198
version-1.4.197
version-1.4.196
version-1.4.195
version-1.4.194
version-1.4.193
version-1.4.192
version-1.4.191
version-1.4.190
version-1.4.188
version-1.4.187
version-1.4.186
version-1.4.185
version-1.4.184
version-1.4.183
version-1.4.182
version-1.4.181
无相关合并请求
显示空白字符变更
内嵌
并排
正在显示
2 个修改的文件
包含
279 行增加
和
0 行删除
+279
-0
ConcurrentLinkedList.java
h2/src/main/org/h2/mvstore/ConcurrentLinkedList.java
+106
-0
TestConcurrentLinkedList.java
h2/src/test/org/h2/test/store/TestConcurrentLinkedList.java
+173
-0
没有找到文件。
h2/src/main/org/h2/mvstore/ConcurrentLinkedList.java
0 → 100644
浏览文件 @
82b73a05
/*
* Copyright 2004-2014 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
.
mvstore
;
import
java.util.Iterator
;
/**
* A very simple linked list that supports concurrent access.
*
* @param <K> the key type
*/
public
class
ConcurrentLinkedList
<
K
>
{
volatile
Entry
<
K
>
head
;
private
volatile
Entry
<
K
>
tail
;
public
K
peekFirst
()
{
Entry
<
K
>
x
=
head
;
return
x
==
null
?
null
:
x
.
obj
;
}
public
K
peekLast
()
{
Entry
<
K
>
x
=
tail
;
return
x
==
null
?
null
:
x
.
obj
;
}
public
void
add
(
K
obj
)
{
Entry
<
K
>
x
=
new
Entry
<
K
>(
obj
);
Entry
<
K
>
t
=
tail
;
if
(
t
!=
null
)
{
t
.
next
=
x
;
}
tail
=
x
;
if
(
head
==
null
)
{
head
=
x
;
}
}
public
void
removeFirst
(
K
obj
)
{
Entry
<
K
>
x
=
head
;
if
(
x
==
null
||
tail
==
x
)
{
throw
DataUtils
.
newUnsupportedOperationException
(
"Must contain at least two entries"
);
}
if
(
x
.
obj
.
equals
(
obj
))
{
head
=
x
.
next
;
}
}
public
void
removeLast
(
K
obj
)
{
Entry
<
K
>
x
=
head
;
Entry
<
K
>
prev
=
x
;
while
(
x
.
next
!=
null
)
{
prev
=
x
;
x
=
x
.
next
;
}
if
(
x
.
obj
.
equals
(
obj
))
{
prev
.
next
=
null
;
if
(
head
==
tail
)
{
head
=
prev
;
}
tail
=
prev
;
}
}
public
Iterator
<
K
>
iterator
()
{
return
new
Iterator
<
K
>()
{
Entry
<
K
>
current
=
head
;
@Override
public
boolean
hasNext
()
{
return
current
!=
null
;
}
@Override
public
K
next
()
{
K
x
=
current
.
obj
;
current
=
current
.
next
;
return
x
;
}
@Override
public
void
remove
()
{
throw
DataUtils
.
newUnsupportedOperationException
(
"remove"
);
}
};
}
/**
* An entry in the linked list.
*/
private
static
class
Entry
<
K
>
{
final
K
obj
;
Entry
<
K
>
next
;
Entry
(
K
obj
)
{
this
.
obj
=
obj
;
}
}
}
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/store/TestConcurrentLinkedList.java
0 → 100644
浏览文件 @
82b73a05
/*
* Copyright 2004-2014 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
.
store
;
import
java.util.Iterator
;
import
java.util.LinkedList
;
import
java.util.Random
;
import
org.h2.mvstore.ConcurrentLinkedList
;
import
org.h2.test.TestBase
;
import
org.h2.util.Task
;
public
class
TestConcurrentLinkedList
extends
TestBase
{
/**
* Run just this test.
*
* @param a ignored
*/
public
static
void
main
(
String
...
a
)
throws
Exception
{
TestBase
.
createCaller
().
init
().
test
();
}
@Override
public
void
test
()
throws
Exception
{
testPerformance
(
true
);
testPerformance
(
false
);
testPerformance
(
true
);
testPerformance
(
false
);
testPerformance
(
true
);
testPerformance
(
false
);
testConcurrent
();
testRandomized
();
}
private
void
testPerformance
(
final
boolean
stock
)
{
System
.
out
.
print
(
stock
?
"stock "
:
"custom "
);
long
start
=
System
.
currentTimeMillis
();
final
ConcurrentLinkedList
<
Integer
>
test
=
new
ConcurrentLinkedList
<
Integer
>();
final
LinkedList
<
Integer
>
x
=
new
LinkedList
<
Integer
>();
Task
task
=
new
Task
()
{
@Override
public
void
call
()
throws
Exception
{
while
(!
stop
)
{
if
(
stock
)
{
synchronized
(
x
)
{
x
.
peekFirst
();
}
}
else
{
test
.
peekFirst
();
}
}
}
};
task
.
execute
();
test
.
add
(-
1
);
x
.
add
(-
1
);
for
(
int
i
=
0
;
i
<
10000000
;
i
++)
{
Integer
value
=
i
;
if
(
stock
)
{
synchronized
(
x
)
{
Integer
f
=
x
.
peekLast
();
if
(!
f
.
equals
(
value
))
{
x
.
add
(
i
);
}
}
synchronized
(
x
)
{
if
(
x
.
peek
()
!=
x
.
peekLast
())
{
x
.
peek
();
x
.
removeFirst
();
}
}
}
else
{
Integer
f
=
test
.
peekLast
();
if
(!
f
.
equals
(
value
))
{
test
.
add
(
i
);
}
if
(
test
.
peekFirst
()
!=
test
.
peekLast
())
{
f
=
test
.
peekFirst
();
test
.
removeFirst
(
f
);
}
}
}
task
.
get
();
System
.
out
.
println
(
System
.
currentTimeMillis
()
-
start
);
}
private
void
testConcurrent
()
{
// TODO Auto-generated method stub
}
private
void
testRandomized
()
{
Random
r
=
new
Random
(
0
);
for
(
int
i
=
0
;
i
<
100
;
i
++)
{
ConcurrentLinkedList
<
Integer
>
test
=
new
ConcurrentLinkedList
<
Integer
>();
LinkedList
<
Integer
>
x
=
new
LinkedList
<
Integer
>();
StringBuilder
buff
=
new
StringBuilder
();
for
(
int
j
=
0
;
j
<
10000
;
j
++)
{
int
opType
=
r
.
nextInt
(
10
);
switch
(
opType
)
{
case
0
:
{
int
value
=
r
.
nextInt
(
100
);
buff
.
append
(
" add "
+
value
);
test
.
add
(
value
);
x
.
add
(
value
);
break
;
}
case
1
:
{
Integer
value
=
x
.
peek
();
buff
.
append
(
" peek"
);
if
(
value
==
null
)
{
assertNull
(
test
.
peekFirst
());
}
else
{
assertEquals
(
value
.
intValue
(),
test
.
peekFirst
().
intValue
());
}
break
;
}
case
2
:
{
Integer
value
=
x
.
peekLast
();
buff
.
append
(
" peeLast"
);
if
(
value
==
null
)
{
assertNull
(
test
.
peekLast
());
}
else
{
assertEquals
(
value
.
intValue
(),
test
.
peekLast
()
.
intValue
());
}
break
;
}
case
3
:
{
if
(
x
.
size
()
>=
2
)
{
Integer
value
=
x
.
peek
();
if
(
value
!=
null
&&
r
.
nextBoolean
())
{
buff
.
append
(
" removeFirst"
);
x
.
removeFirst
();
test
.
removeFirst
(
value
);
}
else
{
test
.
removeFirst
(-
1
);
}
}
break
;
}
case
4
:
{
if
(
x
.
size
()
>=
2
)
{
Integer
value
=
x
.
peekLast
();
if
(
value
!=
null
&&
r
.
nextBoolean
())
{
buff
.
append
(
" removeLast"
);
x
.
removeLast
();
test
.
removeLast
(
value
);
}
else
{
test
.
removeLast
(-
1
);
}
}
break
;
}
}
assertEquals
(
toString
(
x
.
iterator
()),
toString
(
test
.
iterator
()));
}
}
}
private
static
<
T
>
String
toString
(
Iterator
<
T
>
it
)
{
StringBuilder
buff
=
new
StringBuilder
();
while
(
it
.
hasNext
())
{
buff
.
append
(
' '
).
append
(
it
.
next
());
}
return
buff
.
toString
();
}
}
This diff is collapsed.
Click to expand it.
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论