aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/cord.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/cord.erl')
-rw-r--r--src/cord.erl71
1 files changed, 29 insertions, 42 deletions
diff --git a/src/cord.erl b/src/cord.erl
index 980248d..3e131f0 100644
--- a/src/cord.erl
+++ b/src/cord.erl
@@ -1,10 +1,3 @@
-%%%----------------------------------------------------------------------
-%%% File : cord.erl
-%%% Author : Luke Gorrie <luke@bluetail.com>
-%%% Purpose : Data structure for large strings of text
-%%% Created : 21 Oct 2000 by Luke Gorrie <luke@bluetail.com>
-%%%----------------------------------------------------------------------
-%%
%% Cords - a scalable data structure for strings of text.
%%
%% Cords are binary trees with erlang binaries as leaves. The trees
@@ -40,7 +33,6 @@
%% {result, R}.
-module(cord).
--author('luke@bluetail.com').
-compile(export_all).
@@ -75,8 +67,8 @@
new() -> <<>>.
-new(B) when binary(B) -> fix_cord(B);
-new(L) when list(L) -> new(list_to_binary(L)).
+new(B) when is_binary(B) -> fix_cord(B);
+new(L) when is_list(L) -> new(list_to_binary(L)).
%% More efficient way to create a cord from a file. This
%% implementation is not terribly clever (read small chunks, balance
@@ -112,18 +104,18 @@ make_cord(Left, Right) ->
right=Right,
dirty=true}.
-cord_size(Cord) when binary(Cord) ->
+cord_size(Cord) when is_binary(Cord) ->
size(Cord);
-cord_size(Cord) when record(Cord, cord) ->
+cord_size(Cord = #cord{}) ->
Cord#cord.size.
-max_depth(Cord) when binary(Cord) ->
+max_depth(Cord) when is_binary(Cord) ->
1;
max_depth(Cord) ->
1 + max(max_depth(Cord#cord.left),
max_depth(Cord#cord.right)).
-nr_nodes(Cord) when binary(Cord) ->
+nr_nodes(Cord) when is_binary(Cord) ->
1;
nr_nodes(Cord) ->
1 + nr_nodes(Cord#cord.left) + nr_nodes(Cord#cord.right).
@@ -135,14 +127,11 @@ mean_leaf_size(Cord) ->
Sizes),
round(Sum / length(Sizes)).
-leaf_sizes(Cord) when binary(Cord) ->
+leaf_sizes(Cord) when is_binary(Cord) ->
[size(Cord)];
leaf_sizes(Cord) ->
leaf_sizes(Cord#cord.left) ++ leaf_sizes(Cord#cord.right).
-max(X, Y) when X > Y -> X;
-max(X, Y) -> Y.
-
insert(Cord, New, Point) ->
replace(Cord, New, Point, 0).
@@ -151,7 +140,7 @@ delete(Cord, Point, Length) ->
%% replace/4: Replace a region of the cord. `New' is the text to
%% replace the region with, and can be either a list, binary, or cord.
-replace(Cord, New, Start, Length) when list(New) ->
+replace(Cord, New, Start, Length) when is_list(New) ->
replace(Cord, list_to_binary(New), Start, Length);
replace(Cord, New, Start, Length) ->
%% Replace is done by copying the areas on the left and right of
@@ -161,14 +150,14 @@ replace(Cord, New, Start, Length) ->
{C, D} = split(B, Length),
fix_cord(make_cord(make_cord(A, New), D)).
-split(Cord, 0) when binary(Cord) ->
+split(Cord, 0) when is_binary(Cord) ->
{<<>>, Cord};
-split(Cord, Pos) when binary(Cord) ->
+split(Cord, Pos) when is_binary(Cord) ->
?assert(Pos =< cord_size(Cord)),
<<Left:Pos/binary, Right/binary>> = Cord,
{Left, Right};
-split(Cord, Pos) when record(Cord, cord) ->
+split(Cord = #cord{}, Pos) ->
?assert(Pos =< cord_size(Cord)),
LeftSz = cord_size(Cord#cord.left),
RightSz = cord_size(Cord#cord.right),
@@ -184,7 +173,7 @@ split(Cord, Pos) when record(Cord, cord) ->
end.
%% join two cords together and rebalance.
-join(Left, Right) when binary(Left) ->
+join(Left, Right) when is_binary(Left) ->
fix_cord(make_cord(Left, Right)).
%% fix_cord/1
@@ -193,7 +182,7 @@ join(Left, Right) when binary(Left) ->
%% reasonable sizes.
%% Leaf (binary) - break it up if it's too big
-fix_cord(Bin) when binary(Bin) ->
+fix_cord(Bin) when is_binary(Bin) ->
if size(Bin) > ?MAX_SIZE ->
{Left, Right} = split(Bin, round(size(Bin) / 2)),
fix_cord(make_cord(Left, Right));
@@ -204,7 +193,7 @@ fix_cord(Cord) when Cord#cord.dirty == false ->
Cord;
%% Branch (cord) - merge its children if they're too small, balance it
%% if it's too unbalanced.
-fix_cord(Cord) when record(Cord, cord) ->
+fix_cord(Cord = #cord{}) ->
Sz = cord_size(Cord),
Left = Cord#cord.left,
Right = Cord#cord.right,
@@ -217,13 +206,13 @@ fix_cord(Cord) when record(Cord, cord) ->
SzDiff > (Sz/3) ->
%% needs rebalancing
if LeftSz > RightSz ->
- if binary(Left) ->
+ if is_binary(Left) ->
fix_cord(to_binary(Cord));
true ->
balance_from_left(Cord)
end;
LeftSz =< RightSz ->
- if binary(Right) ->
+ if is_binary(Right) ->
fix_cord(to_binary(Cord));
true ->
balance_from_right(Cord)
@@ -238,7 +227,7 @@ fix_cord(Cord) when record(Cord, cord) ->
%% Balance by taking from the left side.
%% Left must be a #cord, right can be a binary.
-balance_from_left(#cord{left=Left, right=Right}) when record(Left, cord) ->
+balance_from_left(#cord{left = Left, right = Right}) when is_record(Left, cord) ->
LLSz = cord_size(Left#cord.left),
LRSz = cord_size(Left#cord.right),
if
@@ -247,7 +236,7 @@ balance_from_left(#cord{left=Left, right=Right}) when record(Left, cord) ->
fix_cord(make_cord(Left#cord.left,
make_cord(Left#cord.right,
Right)));
- record(Left#cord.right, cord) ->
+ is_record(Left#cord.right, cord) ->
%% double rotate
LeftRight = Left#cord.right,
fix_cord(make_cord(make_cord(Left#cord.left,
@@ -260,7 +249,7 @@ balance_from_left(#cord{left=Left, right=Right}) when record(Left, cord) ->
%% oh, pain, duplication. never have been good at taking redundancy
%% out of symmetric functions. -luke
-balance_from_right(#cord{left=Left, right=Right}) when record(Right, cord) ->
+balance_from_right(#cord{left = Left, right = Right}) when is_record(Right, cord) ->
RLSz = cord_size(Right#cord.left),
RRSz = cord_size(Right#cord.right),
if
@@ -269,7 +258,7 @@ balance_from_right(#cord{left=Left, right=Right}) when record(Right, cord) ->
fix_cord(make_cord(make_cord(Left,
Right#cord.left),
Right#cord.right));
- record(Right#cord.left, cord) ->
+ is_record(Right#cord.left, cord) ->
%% double rotate
RightLeft = Right#cord.left,
fix_cord(make_cord(make_cord(Left,
@@ -294,20 +283,20 @@ region_binary(Cord, Start, Length) ->
region_list(Cord, Start, Length) ->
binary_to_list(region_binary(Cord, Start, Length)).
-to_binary(Cord) when binary(Cord) ->
+to_binary(Cord) when is_binary(Cord) ->
Cord;
to_binary(Cord) ->
- list_to_binary(to_binary1(Cord)).
+ to_binary1(Cord).
-to_binary1(Cord) when binary(Cord) ->
+to_binary1(Cord) when is_binary(Cord) ->
Cord;
-to_binary1(Cord) when record(Cord, cord) ->
- [to_binary1(Cord#cord.left),to_binary1(Cord#cord.right)].
+to_binary1(Cord = #cord{left = Left, right = Right}) ->
+ <<(to_binary1(Left))/binary, (to_binary1(Right))/binary>>.
to_list(Cord) ->
binary_to_list(to_binary(Cord)).
-to_iolist(Cord) when binary(Cord) ->
+to_iolist(Cord) when is_binary(Cord) ->
[Cord];
to_iolist(Cord) ->
[to_iolist(Cord#cord.left) | to_iolist(Cord#cord.right)].
@@ -335,7 +324,7 @@ walk(Cord, Pos, Direction, F) ->
walk1(<<>>, Direction, F) ->
{more, F};
-walk1(Bin, Direction, F) when binary(Bin) ->
+walk1(Bin, Direction, F) when is_binary(Bin) ->
{Chunk, Char} = case Direction of
backward ->
Sz = size(Bin) - 1,
@@ -351,7 +340,7 @@ walk1(Bin, Direction, F) when binary(Bin) ->
{result, R} ->
{result, R}
end;
-walk1(Cord, Direction, F) when record(Cord, cord) ->
+walk1(Cord, Direction, F) when is_record(Cord, cord) ->
{First, Second} = case Direction of
backward ->
{Cord#cord.right, Cord#cord.left};
@@ -371,7 +360,7 @@ walker(Cord) ->
walker(Cord, Direction) ->
walker(Cord, Direction, <<>>).
-walker(Cord, Direction, More) when binary(Cord) ->
+walker(Cord, Direction, More) when is_binary(Cord) ->
{Cord, Direction, More};
walker(Cord, forward, More) ->
walker(Cord#cord.left, forward, make_cord(Cord#cord.right, More));
@@ -500,5 +489,3 @@ split_with_each(Cord, [H|T], L, N) ->
split_with_each(Cord, T, L, N);
split_with_each(Cord, [], L, N) ->
split_with_each(Cord, L, L, N-1).
-
-