Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
05c9c737
R
Rust
项目概览
int
/
Rust
大约 1 年 前同步成功
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
Rust
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
05c9c737
编写于
11月 06, 2011
作者:
D
David Rajchenbach-Teller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[Stdlib] rope.rs: improved doc, code readability
上级
7bfe4dba
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
157 addition
and
82 deletion
+157
-82
src/lib/rope.rs
src/lib/rope.rs
+157
-82
未找到文件。
src/lib/rope.rs
浏览文件 @
05c9c737
...
...
@@ -711,6 +711,8 @@ mod node {
const
hint_max_node_height
:
uint
=
16u
;
/*
Function: of_str
Adopt a string as a node.
If the string is longer than `max_leaf_char_len`, it is
...
...
@@ -918,7 +920,11 @@ fn serialize_node(node: @node) -> str unsafe {
}
/*
Function: flatten
Replace a subtree by a single leaf with the same contents.
Performance note: This function executes in linear time.
*/
fn
flatten
(
node
:
@
node
)
->
@
node
unsafe
{
alt
(
*
node
)
{
...
...
@@ -934,49 +940,77 @@ fn flatten(node: @node) -> @node unsafe {
}
}
/*
Function: bal
Balance a node.
Algorithm:
- if the node height is smaller than `hint_max_node_height`, do nothing
- otherwise, gather all leaves as a forest, rebuild a balanced node,
concatenating small leaves along the way
Returns:
- `option::none` if no transformation happened
- `option::some(x)` otherwise, in which case `x` has the same contents
as `node` bot lower height and/or fragmentation.
*/
fn
bal
(
node
:
@
node
)
->
option
::
t
<@
node
>
{
if
height
(
node
)
<
hint_max_node_height
{
ret
option
::
none
}
else
{
//1. Gather all leaves as a forest
let
forest
=
[
mutable
];
let
it
=
leaf_iterator
::
start
(
node
);
while
true
{
alt
(
leaf_iterator
::
next
(
it
))
{
option
::
none
.
{
break
;
}
option
::
some
(
x
)
{
forest
+=
[
mutable
@
leaf
(
x
)];
}
}
if
height
(
node
)
<
hint_max_node_height
{
ret
option
::
none
;
}
//1. Gather all leaves as a forest
let
forest
=
[
mutable
];
let
it
=
leaf_iterator
::
start
(
node
);
while
true
{
alt
(
leaf_iterator
::
next
(
it
))
{
option
::
none
.
{
break
;
}
option
::
some
(
x
)
{
forest
+=
[
mutable
@
leaf
(
x
)];
}
}
//2. Rebuild tree from forest
let
root
=
@*
tree_from_forest_destructive
(
forest
);
ret
option
::
some
(
root
);
}
//2. Rebuild tree from forest
let
root
=
@*
tree_from_forest_destructive
(
forest
);
ret
option
::
some
(
root
);
}
/*
Function: sub_bytes
Compute the subnode of a node.
Parameters:
node - A node
byte_offset - A byte offset in `node`
byte_len - The number of bytes to return
Performance notes:
- this function performs no copying;
- this function executes in a time proportional to the height of `node`.
Safety notes:
- this function fails if `byte_offset` or `byte_len` do not represent
valid positions in `node`.
*/
fn
sub_bytes
(
node
:
@
node
,
byte_offset
:
uint
,
byte_len
:
uint
)
->
@
node
{
let
node
=
node
;
let
result
=
node
;
//Arbitrary value
let
byte_offset
=
byte_offset
;
let
byte_len
=
byte_len
;
while
true
{
if
byte_offset
==
0u
&&
byte_len
==
node
::
byte_len
(
node
)
{
result
=
node
;
break
;
ret
node
;
}
alt
(
*
node
)
{
node
::
leaf
(
x
)
{
let
char_len
=
str
::
char_len_range
(
*
x
.content
,
byte_offset
,
byte_len
);
re
sult
=
@
leaf
({
byte_offset
:
byte_offset
,
re
t
@
leaf
({
byte_offset
:
byte_offset
,
byte_len
:
byte_len
,
char_len
:
char_len
,
content
:
x
.content
});
break
;
}
node
::
concat
(
x
)
{
let
left_len
:
uint
=
node
::
byte_len
(
x
.left
);
if
byte_offset
<=
left_len
{
if
byte_offset
+
byte_len
<=
left_len
{
//Case 1: Everything fits in x.left, tail-call
//Case 1: Everything fits in x.left, tail-call
node
=
x
.left
;
}
else
{
//Case 2: A (non-empty, possibly full) suffix
...
...
@@ -986,8 +1020,7 @@ fn sub_bytes(node: @node, byte_offset: uint, byte_len: uint) -> @node {
sub_bytes
(
x
.left
,
byte_offset
,
left_len
);
let
right_result
=
sub_bytes
(
x
.right
,
0u
,
left_len
-
byte_offset
);
result
=
concat2
(
left_result
,
right_result
);
break
;
ret
concat2
(
left_result
,
right_result
);
}
}
else
{
//Case 3: Everything fits in x.right
...
...
@@ -997,49 +1030,71 @@ fn sub_bytes(node: @node, byte_offset: uint, byte_len: uint) -> @node {
}
}
}
ret
result
;
fail
;
//Note: unreachable
}
/*
Function: sub_chars
Compute the subnode of a node.
Parameters:
node - A node
char_offset - A char offset in `node`
char_len - The number of chars to return
Performance notes:
- this function performs no copying;
- this function executes in a time proportional to the height of `node`.
Safety notes:
- this function fails if `char_offset` or `char_len` do not represent
valid positions in `node`.
*/
fn
sub_chars
(
node
:
@
node
,
char_offset
:
uint
,
char_len
:
uint
)
->
@
node
{
alt
(
*
node
)
{
node
::
leaf
(
x
)
{
if
char_offset
==
0u
&&
char_len
==
x
.char_len
{
ret
node
;
}
let
byte_offset
=
str
::
byte_len_range
(
*
x
.content
,
0u
,
char_offset
);
let
byte_len
=
str
::
byte_len_range
(
*
x
.content
,
byte_offset
,
char_len
);
ret
@
leaf
({
byte_offset
:
byte_offset
,
byte_len
:
byte_len
,
char_len
:
char_len
,
content
:
x
.content
});
}
node
::
concat
(
x
)
{
if
char_offset
==
0u
&&
char_len
==
x
.char_len
{
ret
node
;}
let
left_len
:
uint
=
node
::
char_len
(
x
.left
);
if
char_offset
<=
left_len
{
if
char_offset
+
char_len
<=
left_len
{
//Case 1: Everything fits in x.left
ret
sub_chars
(
x
.left
,
char_offset
,
char_len
);
//TODO: Optimize manually this tail call?
let
node
=
node
;
let
char_offset
=
char_offset
;
while
true
{
alt
(
*
node
)
{
node
::
leaf
(
x
)
{
if
char_offset
==
0u
&&
char_len
==
x
.char_len
{
ret
node
;
}
let
byte_offset
=
str
::
byte_len_range
(
*
x
.content
,
0u
,
char_offset
);
let
byte_len
=
str
::
byte_len_range
(
*
x
.content
,
byte_offset
,
char_len
);
ret
@
leaf
({
byte_offset
:
byte_offset
,
byte_len
:
byte_len
,
char_len
:
char_len
,
content
:
x
.content
});
}
node
::
concat
(
x
)
{
if
char_offset
==
0u
&&
char_len
==
x
.char_len
{
ret
node
;}
let
left_len
:
uint
=
node
::
char_len
(
x
.left
);
if
char_offset
<=
left_len
{
if
char_offset
+
char_len
<=
left_len
{
//Case 1: Everything fits in x.left, tail call
node
=
x
.left
;
}
else
{
//Case 2: A (non-empty, possibly full) suffix
//of x.left and a (non-empty, possibly full) prefix
//of x.right
let
left_result
=
sub_chars
(
x
.left
,
char_offset
,
left_len
);
let
right_result
=
sub_chars
(
x
.right
,
0u
,
left_len
-
char_offset
);
ret
concat2
(
left_result
,
right_result
);
}
}
else
{
//Case 2: A (non-empty, possibly full) suffix
//of x.left and a (non-empty, possibly full) prefix
//of x.right
let
left_result
=
sub_chars
(
x
.left
,
char_offset
,
left_len
);
let
right_result
=
sub_chars
(
x
.right
,
0u
,
left_len
-
char_offset
);
ret
concat2
(
left_result
,
right_result
)
//Case 3: Everything fits in x.right, tail call
node
=
x
.right
;
char_offset
-=
left_len
;
}
}
else
{
//Case 3: Everything fits in x.right
ret
sub_chars
(
x
.right
,
char_offset
-
left_len
,
char_len
);
//TODO: Optimize manually this tail call?
}
}
}
}
fail
;
}
fn
concat2
(
left
:
@
node
,
right
:
@
node
)
->
@
node
{
...
...
@@ -1091,37 +1146,63 @@ fn loop_chars(node: @node, it: block(char) -> bool) -> bool {
})
}
/*
Function: loop_leaves
Loop through a node, leaf by leaf
Parameters:
rope - A node to traverse.
it - A block to execute with each consecutive leaf of the node.
Return `true` to continue, `false` to stop.
Returns:
`true` If execution proceeded correctly, `false` if it was interrupted,
that is if `it` returned `false` at any point.
*/
fn
loop_leaves
(
node
:
@
node
,
it
:
block
(
leaf
)
->
bool
)
->
bool
{
let
result
=
true
;
let
current
=
node
;
while
true
{
alt
(
*
current
)
{
leaf
(
x
)
{
result
=
it
(
x
);
break
;
ret
it
(
x
);
}
concat
(
x
)
{
if
loop_leaves
(
x
.left
,
it
)
{
//non tail call
current
=
x
.right
;
//tail call
}
else
{
result
=
false
;
break
;
ret
false
;
}
}
}
}
ret
result
;
fail
;
//unreachable
}
/*
Function: char_at
Parameters:
pos - A position in the rope
Returns: The character at position `pos`
Safety notes: The function will fail if `pos`
is not a valid position in the rope.
Performance note: This function executes in a time
proportional to the height of the rope + the (bounded)
length of the largest leaf.
*/
fn
char_at
(
node
:
@
node
,
pos
:
uint
)
->
char
{
let
node
=
node
;
let
pos
=
pos
;
let
result
=
'0'
;
while
true
{
alt
(
*
node
)
{
leaf
(
x
)
{
result
=
str
::
char_at
(
*
x
.content
,
pos
);
break
;
ret
str
::
char_at
(
*
x
.content
,
pos
);
}
concat
({
left
:
left
,
right
:
right
,
...
...
@@ -1129,16 +1210,16 @@ fn char_at(node: @node, pos: uint) -> char {
byte_len
:
_
,
height
:
_
})
{
let
left_len
=
char_len
(
left
);
if
left_len
>
pos
{
if
left_len
>
pos
{
node
=
left
;
}
else
{
}
else
{
node
=
right
;
pos
=
pos
-
left_len
;
}
}
}
}
};
ret
result
;
fail
;
//unreachable
}
mod
leaf_iterator
{
...
...
@@ -1162,7 +1243,6 @@ fn start(node: @node) -> t {
fn
next
(
it
:
t
)
->
option
::
t
<
leaf
>
{
if
it
.stackpos
<
0
{
ret
option
::
none
;
}
let
result
=
option
::
none
;
while
true
{
let
current
=
it
.stack
[
it
.stackpos
];
it
.stackpos
-=
1
;
...
...
@@ -1174,12 +1254,11 @@ fn next(it: t) -> option::t<leaf> {
it
.stack
[
it
.stackpos
]
=
x
.left
;
}
leaf
(
x
)
{
result
=
option
::
some
(
x
);
break
;
ret
option
::
some
(
x
);
}
}
}
ret
result
;
fail
;
//unreachable
}
}
...
...
@@ -1207,12 +1286,9 @@ fn empty() -> t {
}
fn
next
(
it
:
t
)
->
option
::
t
<
char
>
{
let
result
=
option
::
none
;
while
true
{
alt
(
get_current_or_next_leaf
(
it
))
{
option
::
none
.
{
break
;
}
option
::
none
.
{
ret
option
::
none
;
}
option
::
some
(
leaf
)
{
let
next_char
=
get_next_char_in_leaf
(
it
);
alt
(
next_char
)
{
...
...
@@ -1220,14 +1296,13 @@ fn next(it: t) -> option::t<char> {
cont
;
}
option
::
some
(
_
)
{
result
=
next_char
;
break
;
ret
next_char
;
}
}
}
}
}
ret
result
;
fail
;
//unreachable
}
fn
get_current_or_next_leaf
(
it
:
t
)
->
option
::
t
<
leaf
>
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录