Skip to content

Commit

Permalink
All spatial Futon tests pass now.
Browse files Browse the repository at this point in the history
  • Loading branch information
vmx committed May 16, 2011
1 parent 0f003f8 commit 5f2cdb8
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 6 deletions.
3 changes: 2 additions & 1 deletion src/geocouch/couch_spatial_compactor.erl
Expand Up @@ -46,7 +46,8 @@ compact_group(Group, EmptyGroup) ->
fd = EmptyFd
} = EmptyGroup,

{ok, {Count, _}} = couch_btree:full_reduce(Db#db.fulldocinfo_by_id_btree),
{ok, DbReduce} = couch_btree:full_reduce(Db#db.fulldocinfo_by_id_btree),
Count = element(1, DbReduce),

<<"_design", ShortName/binary>> = GroupId,
DbName = couch_db:name(Db),
Expand Down
2 changes: 1 addition & 1 deletion src/geocouch/couch_spatial_group.erl
Expand Up @@ -330,7 +330,7 @@ reply_all(#group_state{waiting_list=WaitList}=State, Reply) ->
open_db_group(DbName, DDocId) ->
case couch_db:open_int(DbName, []) of
{ok, Db} ->
case couch_db:open_doc(Db, DDocId) of
case couch_db:open_doc(Db, DDocId, [ejson_body]) of
{ok, Doc} ->
{ok, Db, design_doc_to_spatial_group(Doc)};
Else ->
Expand Down
9 changes: 9 additions & 0 deletions src/vtree/vtree.erl
Expand Up @@ -340,6 +340,7 @@ split_node({_Mbr, Meta, _Entries}=Node) ->
insert(Fd, nil, Id, {Mbr, Meta, Geom, Value}) ->
InitialTree = {Mbr, #node{type=leaf}, [{Mbr, Meta, {Id, {Geom, Value}}}]},
{ok, Pos, _} = couch_file:append_term(Fd, InitialTree),
ok = couch_file:flush(Fd),
{ok, Mbr, Pos, 1};

insert(Fd, RootPos, Id, Node) ->
Expand Down Expand Up @@ -372,6 +373,7 @@ insert(Fd, RootPos, NewNodeId,
EntryNum < ?MAX_FILLED ->
%io:format("There's plenty of space (leaf node)~n", []),
{ok, Pos, _} = couch_file:append_term(Fd, LeafNode),
ok = couch_file:flush(Fd),
{ok, LeafNodeMbr, Pos, CallDepth};
% do the fancy split algorithm
true ->
Expand All @@ -380,6 +382,7 @@ insert(Fd, RootPos, NewNodeId,
= split_node(LeafNode),
{ok, Pos1, _} = couch_file:append_term(Fd, Node1),
{ok, Pos2, _} = couch_file:append_term(Fd, Node2),
ok = couch_file:flush(Fd),
{splitted, SplittedMbr, {Node1Mbr, Pos1}, {Node2Mbr, Pos2},
CallDepth}
end;
Expand Down Expand Up @@ -418,6 +421,7 @@ insert(Fd, RootPos, NewNodeId,
% end of the list.
NewNode2 = {NewMbr, #node{type=inner}, A ++ [ChildPos] ++ tl(B)},
{ok, Pos, _} = couch_file:append_term(Fd, NewNode2),
ok = couch_file:flush(Fd),
{ok, NewMbr, Pos, TreeHeight};
{splitted, ChildMbr, {Child1Mbr, ChildPos1}, {Child2Mbr, ChildPos2},
TreeHeight} ->
Expand All @@ -430,6 +434,7 @@ insert(Fd, RootPos, NewNodeId,
NewNode2 = {NewMbr, #node{type=inner},
A ++ [ChildPos1, ChildPos2] ++ tl(B)},
{ok, Pos, _} = couch_file:append_term(Fd, NewNode2),
ok = couch_file:flush(Fd),
{ok, NewMbr, Pos, TreeHeight};
% We need to split the inner node
true ->
Expand All @@ -446,6 +451,7 @@ insert(Fd, RootPos, NewNodeId,
A ++ [Child1, Child2] ++ tl(B)}),
{ok, Pos1, _} = couch_file:append_term(Fd, Node1),
{ok, Pos2, _} = couch_file:append_term(Fd, Node2),
ok = couch_file:flush(Fd),
{splitted, SplittedMbr, {Node1Mbr, Pos1}, {Node2Mbr, Pos2},
TreeHeight}
end
Expand All @@ -459,6 +465,7 @@ insert(Fd, RootPos, NewNodeId,
NewRoot = {NewRootMbr, #node{type=inner},
[SplittedNode1, SplittedNode2]},
{ok, NewRootPos, _} = couch_file:append_term(Fd, NewRoot),
ok = couch_file:flush(Fd),
{ok, NewRootMbr, NewRootPos, TreeHeight2+1};
_ ->
Inserted
Expand Down Expand Up @@ -695,6 +702,7 @@ delete(Fd, DeleteId, DeleteMbr, [NodePos|NodePosTail]) ->
NodeMbrNew = calc_nodes_mbr(EntriesNew),
{ok, NodeNewPos, _} = couch_file:append_term(Fd,
{NodeMbrNew, NodeMeta, EntriesNew}),
ok = couch_file:flush(Fd),
% NodePos is the old position in file
{ok, NodeNewPos, NodePos}
end;
Expand All @@ -712,6 +720,7 @@ rebuild_node(Fd, NodeMeta, EntriesPos) ->
Entries = pos_to_data(Fd, EntriesPos),
Mbr = calc_nodes_mbr(Entries),
{ok, NodePos, _} = couch_file:append_term(Fd, {Mbr, NodeMeta, EntriesPos}),
ok = couch_file:flush(Fd),
NodePos.

% It's a bit like lists:keytake/3, but uses a function that returns a key
Expand Down
27 changes: 23 additions & 4 deletions src/vtree/vtree_bulk.erl
Expand Up @@ -75,10 +75,14 @@ bulk_load(Fd, _RootPos, TargetTreeHeight, Nodes) when TargetTreeHeight==0 ->
{_Mbrs, PosList} = lists:unzip(MbrAndPosList),
NewNodes = load_nodes(Fd, PosList),
{ok, NewPos, _} = case length(NewNodes) of
% single node as root
1 -> couch_file:append_term(Fd, hd(NewNodes));
% multiple nodes
_ -> write_parent(Fd, NewNodes)
% single node as root
1 ->
Written = couch_file:append_term(Fd, hd(NewNodes)),
ok = couch_file:flush(Fd),
Written;
% multiple nodes
_ ->
write_parent(Fd, NewNodes)
end,
{ok, NewPos, TreeHeight};
bulk_load(Fd, RootPos, TargetTreeHeight, Nodes) ->
Expand All @@ -105,6 +109,7 @@ bulk_load(Fd, RootPos, TargetTreeHeight, Nodes) ->
% single node as root
1 ->
{ok, ResultPos, _} = couch_file:append_term(Fd, hd(Result)),
ok = couch_file:flush(Fd),
{ResultPos, NewHeight, element(1, hd(Result))};
% multiple nodes
_ ->
Expand Down Expand Up @@ -148,6 +153,7 @@ insert_outliers(Fd, TargetPos, TargetMbr, TargetHeight, Nodes) ->
% XXX vmx: is using type=inner always valid?
NewRootNode = {MergedMbr, #node{type=inner}, [TargetPos|PosList]},
{ok, NewOmtPos, _} = couch_file:append_term(Fd, NewRootNode),
ok = couch_file:flush(Fd),
{NewOmtPos, TargetHeight+1};
% split the node and create new root node
true ->
Expand Down Expand Up @@ -175,6 +181,7 @@ insert_outliers(Fd, TargetPos, TargetMbr, TargetHeight, Nodes) ->
OmtRootNode = {vtree:calc_mbr(OmtRootMbrs), #node{type=inner},
OmtRootPosList},
{ok, NewOmtPos, _} = couch_file:append_term(Fd, OmtRootNode),
ok = couch_file:flush(Fd),
{ok, _, SubPos, Inc} = insert_subtree(
Fd, NewOmtPos, [{TargetMbr, TargetPos}], abs(Diff)),
{SubPos, OmtHeight+Inc}
Expand Down Expand Up @@ -257,11 +264,13 @@ omt_write_tree(Fd, [H|_T]=Leafs, _Depth, _Acc) when is_tuple(H) ->
false ->
PosList = lists:map(fun(N) ->
{ok, Pos, _} = couch_file:append_term(Fd, N),
ok = couch_file:flush(Fd),
Pos
end, Leafs),
{Mbr, #node{type=inner}, PosList}
end,
{ok, Pos, _} = couch_file:append_term(Fd, Node),
ok = couch_file:flush(Fd),
{leaf_nodes, {Mbr, Pos}};
omt_write_tree(Fd, [H|T], Depth, Acc) ->
{_, Acc2} = case omt_write_tree(Fd, H, Depth+1, []) of
Expand All @@ -275,6 +284,7 @@ omt_write_tree(Fd, [H|T], Depth, Acc) ->
Mbr = vtree:calc_mbr(Mbrs),
Meta = #node{type=inner},
{ok, Pos, _} = couch_file:append_term(Fd, {Mbr, Meta, Children}),
ok = couch_file:flush(Fd),
{ok, [{Mbr, Pos}|Acc]}
end,
{_, Acc3} = omt_write_tree(Fd, T, Depth, Acc2),
Expand Down Expand Up @@ -647,6 +657,7 @@ seedtree_write_insert(Fd, Orig, OmtTree, _OmtHeight) ->
false -> #node{type=inner}
end,
{ok, ParentPos, _} = couch_file:append_term(Fd, {ParentMbr, Meta, Pos}),
ok = couch_file:flush(Fd),
{ParentMbr, ParentPos}
end, NewNodes),

Expand Down Expand Up @@ -717,6 +728,7 @@ write_nodes(_Fd, [], Acc) ->
lists:reverse(Acc);
write_nodes(Fd, [H|T], Acc) ->
{ok, Pos, _} = couch_file:append_term(Fd, H),
ok = couch_file:flush(Fd),
write_nodes(Fd, T, [Pos|Acc]).

% @doc Write a list of of nodes to disk with corresponding parent node. Return
Expand All @@ -729,6 +741,7 @@ write_parent(Fd, Nodes) ->
ChildrenPos = write_nodes(Fd, Nodes),
{ok, ParentPos, Length} = couch_file:append_term(
Fd, {ParentMbr, #node{type=inner}, ChildrenPos}),
ok = couch_file:flush(Fd),
{ok, ParentPos, Length}.

% XXX vmx: insert_subtree and potentially other functions should be moved
Expand All @@ -744,6 +757,7 @@ insert_subtree(Fd, RootPos, Subtree, Level) ->
{splitted, NodeMbr, {_Node1Mbr, NodePos1}, {_Node2Mbr, NodePos2}, Inc} ->
Parent = {NodeMbr, #node{type=inner}, [NodePos1, NodePos2]},
{ok, Pos, _} = couch_file:append_term(Fd, Parent),
ok = couch_file:flush(Fd),
{ok, NodeMbr, Pos, Inc+1};
{ok, NewMbr, NewPos, Inc} ->
{ok, NewMbr, NewPos, Inc}
Expand All @@ -766,6 +780,7 @@ insert_subtree(Fd, RootPos, Subtree, Level, Depth) when Depth==Level ->
length(ChildrenPos) =< ?MAX_FILLED ->
NewNode = {MergedMbr, ParentMeta, ChildrenPos},
{ok, Pos, _} = couch_file:append_term(Fd, NewNode),
ok = couch_file:flush(Fd),
{ok, MergedMbr, Pos, 0};
true ->
Children = load_nodes(Fd, ChildrenPos),
Expand All @@ -790,6 +805,7 @@ insert_subtree(Fd, RootPos, Subtree, Level, Depth) when Depth==Level ->
Node2 = {Mbr2, #node{type=inner}, Part2Pos},
{ok, Pos1, _} = couch_file:append_term(Fd, Node1),
{ok, Pos2, _} = couch_file:append_term(Fd, Node2),
ok = couch_file:flush(Fd),

{splitted, MergedMbr, {Mbr1, Pos1}, {Mbr2, Pos2}, 0}
end;
Expand All @@ -809,6 +825,7 @@ insert_subtree(Fd, RootPos, Subtree, Level, Depth) ->
MergedMbr = vtree:merge_mbr(ParentMbr, NewMbr),
NewNode = {MergedMbr, #node{type=inner}, [NewPos|LeastRestPos]},
{ok, Pos, _} = couch_file:append_term(Fd, NewNode),
ok = couch_file:flush(Fd),
{ok, NewMbr, Pos, Inc};
{splitted, ChildMbr, {Child1Mbr, ChildPos1}, {Child2Mbr, ChildPos2}, Inc} ->
MergedMbr = vtree:merge_mbr(ParentMbr, ChildMbr),
Expand All @@ -820,6 +837,7 @@ insert_subtree(Fd, RootPos, Subtree, Level, Depth) ->
ChildrenPos = [ChildPos1, ChildPos2] ++ LeastRestPos,
NewNode = {MergedMbr, #node{type=inner}, ChildrenPos},
{ok, Pos, _} = couch_file:append_term(Fd, NewNode),
ok = couch_file:flush(Fd),
{ok, MergedMbr, Pos, Inc};
% We need to split the inner node
true ->
Expand All @@ -836,6 +854,7 @@ insert_subtree(Fd, RootPos, Subtree, Level, Depth) ->
= vtree:split_node({MergedMbr, #node{type=inner}, Children2}),
{ok, Pos1, _} = couch_file:append_term(Fd, Node1),
{ok, Pos2, _} = couch_file:append_term(Fd, Node2),
ok = couch_file:flush(Fd),
{splitted, SplittedMbr, {Node1Mbr, Pos1}, {Node2Mbr, Pos2}, Inc}
end
end.
Expand Down

0 comments on commit 5f2cdb8

Please sign in to comment.