[erlang-questions] Writing a Concurrent Binary Search Tree Data Structure in Erlang
Fuad Tabba
fuad@REDACTED
Mon Jun 30 06:21:09 CEST 2008
Thanks for everyone's replies. I finished writing the concurrent
implementation of a bst, including delete. I think it's correct, but I
haven't done any extensive testing, just some tests and some reasoning
(which doesn't even begin to be enough, I know). I wanted to see what you
think about this implementation:-
http://www.cs.auckland.ac.nz/~fuad/pbst.erl
The functions that perform insert or delete don't have any feedback
mechanism, which I don't think is necessary since any later call to any
other function should be ordered properly, but this is making benchmarking a
bit of a challenge. I can't think of a way to measure how well this performs
without implementing an acknowledgement mechanism. Any ideas?
I'm also not too happy with the process overhead per node; it's not a big
deal if each node stores a lot of data, but it is quite significant for
small nodes.
Thanks,
/Fuad
On Fri, Jun 27, 2008 at 8:54 AM, Fuad Tabba <fuad@REDACTED> wrote:
> Cool, that's matches my understanding of Hynek's suggestion as well. Thanks
> Kevin.
>
> I'm actually writing code along similar lines to test out the idea. It
> seems rather simple and elegant; what I don't like though is the added
> overhead of a process per node - I know that Erlang processes are light, but
> if I recall correctly from reading in Joe's book, each process has memory
> overhead in the order of 100 bytes. If the the data per node is large then
> it's not a big deal, but if the amount of data stored per node is small then
> that could be some serious overhead.
>
> Implementing delete() is going to be a bit tricky, need to be wary of
> deadlocks; but this isn't an Erlang issue, this is a general issue with
> writing a concurrent and shared data structure.
>
> Thanks again!
>
> Cheers,
> /Fuad
>
> On Fri, Jun 27, 2008 at 8:22 AM, Kevin Scaldeferri <kevin@REDACTED>
> wrote:
>
>>
>> On Jun 25, 2008, at 3:10 PM, Fuad Tabba wrote:
>>
>> I think I understand what you're saying here; but I still can't wrap my
>>> head around putting that into code. Is there similar code that you know of
>>> available online? The structure doesn't have to be a BST, just anything that
>>> demonstrates the idea of having a structure that stores lots persistent data
>>> to be viewed/modified by many processes and is scalable...
>>>
>>>
>>> On Wed, Jun 25, 2008 at 9:40 PM, Hynek Vychodil <
>>> vychodil.hynek@REDACTED> wrote:
>>> Because there is no shared state between processes in Erlang, I would
>>> start think about process per tree node, not process per action as usual in
>>> classic shared memory (for example C) implementations.
>>> I know, it sounds weird, but may be help you :-)
>>>
>>
>>
>>
>> Here's a basic outline of this idea, if I understand it right. delete()
>> is not implemented, and it has some other deficiencies, but I hope it at
>> least starts to demonstrate the idea of a recursive data structure
>> represented as a collection of processes.
>>
>>
>> -kevin
>>
>> %%%%%%%%%%%%%%%%%%%%%%%%%
>>
>> -module(cbst).
>> -export([new/1, exists/2, insert/2, delete/2]).
>>
>> -record(node, {key,
>> left=null,
>> right=null}).
>>
>> %%
>> %% public API
>> %%
>>
>> new(Key) ->
>> spawn(fun() -> create(Key) end).
>>
>> exists(Node, Key) ->
>> Node ! {exists, Key, self()},
>> receive
>> true -> true;
>> false -> false
>> end.
>>
>> insert(Node, Key) ->
>> Node ! {insert, Key}.
>>
>> delete(Node, Key) ->
>> Node ! {delete, Key}.
>>
>>
>> %%
>> %% private functions
>> %%
>>
>> create(Key) ->
>> Node = #node{key=Key},
>> loop(Node).
>>
>> loop(Node) ->
>> receive
>> {exists, Key, Caller}=Q ->
>> case Node#node.key of
>> Key ->
>> Caller ! true;
>> This when Key < This, Node#node.left =/= null ->
>> Node#node.left ! Q;
>> This when Key > This, Node#node.right =/= null ->
>> Node#node.right ! Q;
>> _ ->
>> Caller ! false
>> end,
>> loop(Node);
>> {insert, Key} ->
>> case Node#node.key of
>> Key ->
>> loop(Node); % already in tree
>> This when Key < This ->
>> case Node#node.left of
>> null ->
>> Left = new(Key),
>> loop(Node#node{left=Left});
>> Left ->
>> Left ! {insert, Key},
>> loop(Node)
>> end;
>> This when Key > This ->
>> case Node#node.right of
>> null ->
>> Right = new(Key),
>> loop(Node#node{right=Right});
>> Right ->
>> Right ! {insert, Key},
>> loop(Node)
>> end
>> end;
>> {delete, Key} ->
>> % left as an exercise for the reader
>> loop(Node)
>> end.
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20080630/8713558f/attachment.htm>
More information about the erlang-questions
mailing list