| Author |
Message |
|
| Guest |
Posted: Fri Sep 23, 2011 4:19 pm |
|
|
|
Guest
|
I'm writing a forum engine that can sustain high amount of users
making queries at the same time.
I'm using a KV storage that stores erlang entities which is the way to
kill overheads and make data accessible really fast (if we know the
key, ofc).
The problem I'm facing is full-text search, as you might guess.
I don't really want to use any external indexers or databases because
I want that piece of software to be scalable node-wise and don't want
to add any more data storage entites to the system to prevent data
duplication and to ensure consistency.
So what I want to do is to "invent bicycle" by implementing a full
text search on a key-value storage.
Here I'll outline my plan for writing that feature and I'd be happy to
hear criticism.
A simplistic way to think of a full text search engine is a strict
text search engine, when the result of a search is a list of messages
(posts) that contain full search keywords (if we search for "abc" only
"abc" words are matched, so that "abcd" won't match).
In order to accomplish that I can think of the following things to do:
1) We make a set of all words W
2) For each w \in W we have an "index" I_w which returns a list of all
posts that contain w
When we add a pure full text search functionality (indeed, we might
want "geology" to match "geologist") we do the following:
1) make a set of normalized words W_n
2) make a set of common prefixes P
3) make a set of common suffixes S
4) define a normalization function f that strips common suffixes and
prefixes from a word
5) define a matching function m that maps f(w) to a list of words from
the W_n set
5.1)
6) for each w in W_n we keep an "index" W_n that returns all the
messages M for which \exists x \in M : m(f(x)) = w
7) for each word m in new message
_______________________________________________
erlang-questions mailing list
erlang-questions@erlang.org
http://erlang.org/mailman/listinfo/erlang-questions
Post received from mailinglist |
|
|
| Back to top |
|
| Guest |
Posted: Fri Sep 23, 2011 4:59 pm |
|
|
|
Guest
|
On Fri, Sep 23, 2011 at 18:19, Oleg Chernyh <erlang@udaff.com> wrote:
> 1) We make a set of all words W
Two structures immediately suggest themselves:
* Tries. That is store a digital tree on the word. "CAT" will search
in a 26-way tree through the C-edge, the A-edge and the T-edge. If you
need a base 62 or a base 36 match, it may be beneficial to compress
nodes that are not totally full. An evil way is to use an ets table
with the compressed flag set and call ets:lookup_element/3 on the
beast. This is how a spelling checker often stores its dictionary.
* Bloom filter based structures. Look at how postgresql does it with
GiST indexes for instance:
http://www.postgresql.org/docs/8.3/static/textsearch-indexes.html
For each w \in document, you hash word, h(w) = n, and set the n'th bit
in a bit string. Then you or all hashes together \/_{w \in D} h(w).
This gives an approximate match, but hopefully it weeds out a lot of
things you need to search and the amount of false positives is
probably small. These bit strings can be stored as e.g., crit-bit
trees (also called radix or patricia trees - another trie-structure,
but this time binary). See for instance,
http://cr.yp.to/critbit.html by Dan Bernstein.
I did a crit-bit tree structure in Erlang some months ago,
https://github.com/jlouis/bench-map/blob/master/src/patricia.erl and
also one based on Hash-array Mapped Tries (HAMT, the basic data
structure in Clojures dictionaries),
https://github.com/jlouis/bench-map/blob/master/src/hamt.erl .. While
they do not outperform dict, gb_trees and Robert Virdings RB trees for
the workloads I've tried, the performance isn't too bad and they will
probably pack much better for this kind of thing.
Do note however that this is quite specialized and you can probably
win some raw speed by using a pre-baked solution. My suggestions
should take you up in speed by quite a lot, however.
--
J.
_______________________________________________
erlang-questions mailing list
erlang-questions@erlang.org
http://erlang.org/mailman/listinfo/erlang-questions
Post received from mailinglist |
|
|
| Back to top |
|
| Guest |
Posted: Fri Sep 23, 2011 5:42 pm |
|
|
|
Guest
|
I'm writing a forum engine that can sustain high amount of users
making queries at the same time.
I'm using a KV storage that stores erlang entities which is the way to
kill overheads and make data accessible really fast (if we know the
key, ofc).
The problem I'm facing is full-text search, as you might guess.
I don't really want to use any external indexers or databases because
I want that piece of software to be scalable node-wise and don't want
to add any more data storage entites to the system to prevent data
duplication and to ensure consistency.
So what I want to do is to "invent bicycle" by implementing a full
text search on a key-value storage.
Here I'll outline my plan for writing that feature and I'd be happy to
hear criticism.
A simplistic way to think of a full text search engine is a strict
text search engine, when the result of a search is a list of messages
(posts) that contain full search keywords (if we search for "abc" only
"abc" words are matched, so that "abcd" won't match).
In order to accomplish that I can think of the following things to do:
1) We make a set of all words W
2) For each w \in W we have an "index" I_w which returns a list of all
posts that contain w
When we add a pure full text search functionality (indeed, we might
want "geology" to match "geologist") we do the following:
1) make a set of normalized words W_n
2) make a set of common prefixes P
3) make a set of common suffixes S
4) define a normalization function f that strips common suffixes and
prefixes from a word
5) define a matching function m that maps f(w) to a list of words from
the W_n set
5.1) if there is no adequate entry for f(w), m function adds f(w) to W_n
6) for each w in W_n we keep an "index" W_n that returns all the
messages M for which \exists x \in M : m(f(x)) = w
7) for each word x in new message we asynchronously run m(f(x)) and
update indexes appropriately
from time to time we re-index our W_n maps merging indexes for
similar words
What are the pitfalls of that approach? Any feedback will be appreciated.
-
Oleg
_______________________________________________
erlang-questions mailing list
erlang-questions@erlang.org
http://erlang.org/mailman/listinfo/erlang-questions
Post received from mailinglist |
|
|
| Back to top |
|
| Guest |
Posted: Fri Sep 23, 2011 10:28 pm |
|
|
|
Guest
|
Oleg,
I know you said you don't want to use an external solution but perhaps Riak [1] is an exception given it's design to scale out and the fact that it's written in Erlang? |
|
|
| Back to top |
|
| Guest |
Posted: Fri Sep 23, 2011 11:11 pm |
|
|
|
Guest
|
And if you really wanted to do everything the hard way, you could
probably manage to re-use some of the components that are in Riak.
Would be far simpler to just use Riak as-is though.
On Fri, Sep 23, 2011 at 3:27 PM, Ryan Zezeski <rzezeski@basho.com> wrote:
> Oleg,
> I know you said you don't want to use an external solution but perhaps Riak
> [1] is an exception given it's design to scale out and the fact that it's
> written in Erlang? It has full-text search capability [2]. Might be worth
> a look.
> -Ryan
>
> [1]: http://wiki.basho.com/Riak.html
> [2]: http://wiki.basho.com/Riak-Search.html
> On Fri, Sep 23, 2011 at 12:19 PM, Oleg Chernyh <erlang@udaff.com> wrote:
>>
>> I'm writing a forum engine that can sustain high amount of users making
>> queries at the same time.
>> I'm using a KV storage that stores erlang entities which is the way to
>> kill overheads and make data accessible really fast (if we know the key,
>> ofc).
>> The problem I'm facing is full-text search, as you might guess.
>> I don't really want to use any external indexers or databases because I
>> want that piece of software to be scalable node-wise and don't want to add
>> any more data storage entites to the system to prevent data duplication and
>> to ensure consistency.
>> So what I want to do is to "invent bicycle" by implementing a full text
>> search on a key-value storage.
>>
>> Here I'll outline my plan for writing that feature and I'd be happy to
>> hear criticism.
>>
>> A simplistic way to think of a full text search engine is a strict text
>> search engine, when the result of a search is a list of messages (posts)
>> that contain full search keywords (if we search for "abc" only "abc" words
>> are matched, so that "abcd" won't match).
>> In order to accomplish that I can think of the following things to do:
>> 1) We make a set of all words W
>> 2) For each w \in W we have an "index" I_w which returns a list of all
>> posts that contain w
>>
>> When we add a pure full text search functionality (indeed, we might want
>> "geology" to match "geologist") we do the following:
>> 1) make a set of normalized words W_n
>> 2) make a set of common prefixes P
>> 3) make a set of common suffixes S
>> 4) define a normalization function f that strips common suffixes and
>> prefixes from a word
>> 5) define a matching function m that maps f(w) to a list of words from the
>> W_n set
>> 5.1)
>> 6) for each w in W_n we keep an "index" W_n that returns all the messages
>> M for which \exists x \in M : m(f(x)) = w
>> 7) for each word m in new message
>>
>> _______________________________________________
>> erlang-questions mailing list
>> erlang-questions@erlang.org
>> http://erlang.org/mailman/listinfo/erlang-questions
>
>
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@erlang.org
> http://erlang.org/mailman/listinfo/erlang-questions
>
>
_______________________________________________
erlang-questions mailing list
erlang-questions@erlang.org
http://erlang.org/mailman/listinfo/erlang-questions
Post received from mailinglist |
|
|
| Back to top |
|
| Guest |
Posted: Fri Sep 23, 2011 11:40 pm |
|
|
|
Guest
|
I actually had a look at Riak, I might even give it a try at some other project of mine.
Thank you for your input anyway.
----- Reply message -----
From: "Ryan Zezeski" <rzezeski@basho.com>
Date: Sat, Sep 24, 2011 1:27 am
Subject: [erlang-questions] Full text search in KV-storage.
To: "Oleg Chernyh" <erlang@udaff.com>
Cc: <erlang-questions@erlang.org>
Oleg,
I know you said you don't want to use an external solution but perhaps Riak
[1] is an exception given it's design to scale out and the fact that it's
written in Erlang? |
|
|
| Back to top |
|
| Guest |
Posted: Fri Sep 23, 2011 11:59 pm |
|
|
|
Guest
|
Jesper, thank you for the insights.
I'm far from linguistics and full text search engines, do your input was particulary useful.
And what about my idea that I have briefly described?
I'm sure that it has many flaws such as m-lookup and re-indexing problem, but that's how I store non-full text search indexes at the moment such as tag searches and searches by author. So my mind was spinning around the idea of homogeneous O(1) indexes.
To those who suggest using 3rd party storages - too much of the current logic relies on a "native" storage I currently use so I'd be glad to stick with it.
----- Reply message -----
From: "Jesper Louis Andersen" <jesper.louis.andersen@gmail.com>
Date: Fri, Sep 23, 2011 7:58 pm
Subject: [erlang-questions] Full text search in KV-storage.
To: "Oleg Chernyh" <erlang@udaff.com>
Cc: <erlang-questions@erlang.org>
On Fri, Sep 23, 2011 at 18:19, Oleg Chernyh <erlang@udaff.com> wrote:
> 1) We make a set of all words W
Two structures immediately suggest themselves:
* Tries. That is store a digital tree on the word. "CAT" will search
in a 26-way tree through the C-edge, the A-edge and the T-edge. If you
need a base 62 or a base 36 match, it may be beneficial to compress
nodes that are not totally full. An evil way is to use an ets table
with the compressed flag set and call ets:lookup_element/3 on the
beast. This is how a spelling checker often stores its dictionary.
* Bloom filter based structures. Look at how postgresql does it with
GiST indexes for instance:
http://www.postgresql.org/docs/8.3/static/textsearch-indexes.html
For each w \in document, you hash word, h(w) = n, and set the n'th bit
in a bit string. Then you or all hashes together \/_{w \in D} h(w).
This gives an approximate match, but hopefully it weeds out a lot of
things you need to search and the amount of false positives is
probably small. These bit strings can be stored as e.g., crit-bit
trees (also called radix or patricia trees - another trie-structure,
but this time binary). See for instance,
http://cr.yp.to/critbit.html by Dan Bernstein.
I did a crit-bit tree structure in Erlang some months ago,
https://github.com/jlouis/bench-map/blob/master/src/patricia.erl and
also one based on Hash-array Mapped Tries (HAMT, the basic data
structure in Clojures dictionaries),
https://github.com/jlouis/bench-map/blob/master/src/hamt.erl .. While
they do not outperform dict, gb_trees and Robert Virdings RB trees for
the workloads I've tried, the performance isn't too bad and they will
probably pack much better for this kind of thing.
Do note however that this is quite specialized and you can probably
win some raw speed by using a pre-baked solution. My suggestions
should take you up in speed by quite a lot, however.
--
J.
Post received from mailinglist |
|
|
| Back to top |
|
| Guest |
Posted: Sat Sep 24, 2011 3:27 pm |
|
|
|
Guest
|
On Sat, Sep 24, 2011 at 01:58, Oleg Chernyh <erlang@udaff.com> wrote:
> I'm far from linguistics and full text search engines, do your input was
> particulary useful.
> And what about my idea that I have briefly described?
I tried to be adept and avoid answering those parts because I know
very little about it. It looks like you do some stemming of words to
find their stem and then you index those. But I don't know what you do
to achieve it. If you pick a language, like english there are probably
two ways to go: 1. Form a set of rules and apply those rules to
"normalize"/"canonicalize"/"extract-the-stem". 2. Play the google
game: If you have enough data to mine statistically, figure out what
the stems are via machine learning.
Historically, judging by papers at AI/ML conferences, it looks like
option 2 wins
--
J.
_______________________________________________
erlang-questions mailing list
erlang-questions@erlang.org
http://erlang.org/mailman/listinfo/erlang-questions
Post received from mailinglist |
|
|
| Back to top |
|
| Guest |
Posted: Sat Sep 24, 2011 5:45 pm |
|
|
|
Guest
|
I implemented this on Redis with node.js last year. It was pretty easy, and worked OK, but it wasn't Amazon Product Search by any means.
The mapping from word -> document is going to be pretty big in RAM, because the value for each key needs to be your unique identifier for each document -- I imagine you don't want to die when you reach 4 billion posts. (Actually, on Erlang, I think the limit for small ints is 28 bits, or about 256 million)
Most sites that operate these things for real, though, just use some off-the-shelf index, like Apache Lucene or whatever (Solr wraps that pretty well). Yes, it's another system, but it's a system that already works and scales
Or they delegate to Google Site Search.
Sincerely,
jw
--
Americans might object: there is no way we would sacrifice our living standards for the benefit of people in the rest of the world. Nevertheless, whether we get there willingly or not, we shall soon have lower consumption rates, because our present rates are unsustainable.
On Fri, Sep 23, 2011 at 10:42 AM, Oleg Chernyh <erlang@udaff.com (erlang@udaff.com)> wrote:
Quote: I'm writing a forum engine that can sustain high amount of users making queries at the same time.
I'm using a KV storage that stores erlang entities which is the way to kill overheads and make data accessible really fast (if we know the key, ofc).
The problem I'm facing is full-text search, as you might guess.
I don't really want to use any external indexers or databases because I want that piece of software to be scalable node-wise and don't want to add any more data storage entites to the system to prevent data duplication and to ensure consistency.
So what I want to do is to "invent bicycle" by implementing a full text search on a key-value storage.
Here I'll outline my plan for writing that feature and I'd be happy to hear criticism.
A simplistic way to think of a full text search engine is a strict text search engine, when the result of a search is a list of messages (posts) that contain full search keywords (if we search for "abc" only "abc" words are matched, so that "abcd" won't match).
In order to accomplish that I can think of the following things to do:
1) We make a set of all words W
2) For each w \in W we have an "index" I_w which returns a list of all posts that contain w
When we add a pure full text search functionality (indeed, we might want "geology" to match "geologist") we do the following:
1) make a set of normalized words W_n
2) make a set of common prefixes P
3) make a set of common suffixes S
4) define a normalization function f that strips common suffixes and prefixes from a word
5) define a matching function m that maps f(w) to a list of words from the W_n set
5.1) if there is no adequate entry for f(w), m function adds f(w) to W_n
6) for each w in W_n we keep an "index" W_n that returns all the messages M for which \exists x \in M : m(f(x)) = w
7) for each word x in new message we asynchronously run m(f(x)) and update indexes appropriately
 from time to time we re-index our W_n maps merging indexes for similar words
What are the pitfalls of that approach? Any feedback will be appreciated.
-
Oleg
______________________________ _________________
erlang-questions mailing list
erlang-questions@erlang.org (erlang-questions@erlang.org)
http://erlang.org/mailman/listinfo/erlang-questions
Post received from mailinglist |
|
|
| Back to top |
|
| Guest |
Posted: Sat Sep 24, 2011 9:04 pm |
|
|
|
Guest
|
Hi, Oleg,
Your idea may work pretty well, but there are few points you should consider:
1. at high number of posts, you may want to switch from int (the numbering the posts) in something more roomy;
2. if you build such a system even for one language, the dictionary database will be enormous and some parts will contain no posts (therefore, you should start ranking your dictionary entries, so, the least important to be at the end and not necessary loaded in RAM);
3. such a mapping implies that you know that language pretty well (pretty close to the level of a linguist);
4. I know no language which doesn't have differences in between the literature language and the spoken language (therefore, you may need another mapping from spoken to literature language).
And there are other problems coming from such an approach.
As Jesper said, an AI/ML approach would help to improve your approach, if I understood his message correctly. That means, in a simplistic way of putting it, do not create a vocabulary from the beginning, but allow vocabulary entries with ranking on them. Of course, that will not help you at all in finding meaningful prefixes and suffixes, but it will help you in retrieving faster the posts as many people will hit the peak of your ranking system. This approach will also allow humans to decide what is more relevant and what is less relevant (let's not forget human languages are quite illogic and, therefore, inventing algorithms to mimic human languages is not so easy).
I would also add a system to increment the post number which should allow expansion beyond the basic data types sizes (maybe pagination wouldn't be a bad idea).
Well, that's my 2c opinion. I hope it will help you in thinking your idea.
Good luck!
CGS
On Sat, Sep 24, 2011 at 5:27 PM, Jesper Louis Andersen <jesper.louis.andersen@gmail.com (jesper.louis.andersen@gmail.com)> wrote:
Quote: On Sat, Sep 24, 2011 at 01:58, Oleg Chernyh <erlang@udaff.com (erlang@udaff.com)> wrote:
> I'm far from linguistics and full text search engines, do your input was
> particulary useful.
> And what about my idea that I have briefly described?
I tried to be adept and avoid answering those parts because I know
very little about it. It looks like you do some stemming of words to
find their stem and then you index those. But I don't know what you do
to achieve it. If you pick a language, like english there are probably
two ways to go: 1. Form a set of rules and apply those rules to
"normalize"/"canonicalize"/"extract-the-stem". 2. Play the google
game: If you have enough data to mine statistically, figure out what
the stems are via machine learning.
Historically, judging by papers at AI/ML conferences, it looks like
option 2 wins
--
J.
_______________________________________________
erlang-questions mailing list
erlang-questions@erlang.org (erlang-questions@erlang.org)
http://erlang.org/mailman/listinfo/erlang-questions
Post received from mailinglist |
|
|
| Back to top |
|
| Guest |
Posted: Sun Sep 25, 2011 2:58 pm |
|
|
|
Guest
|
Hello,
I wrote a full-text index in Erlang a while back. It's part of elib1
which can be found
at https://github.com/joearms/elib1
elib1 contain a lot-lot more than just an index so it may not be
apparent how to use
it - you have to first install elib1 to even read the documentation
(which is probably
a mistake).
The indexer in elib1 is a more-or-less literal translation of the algorithms
in the book "Managing Gigabytes" by I.A.Witten, A.Moffat and T.C. Bell.
(and by the way, implementing a full-text indexer without having read the above
is a foolish thing to do - and I should know since I wrote two
full-text indexer before
reading this
The tricky bits in an indexer are creating the inverted index (hint
use the erlang
module file_sorter.erl (in the standard distribution) this is
blazingly fast and possible
my favorite "module in the Erlang distribution that nobody has ever
heard of but which is
amazingly good". The you have to compress the index - I use gamma compression
described in the above book and implemented in
https://github.com/joearms/elib1/blob/master/lib/src/elib1_gamma.erl.
Index entries are represented by a variable bit length code. The
trickiest part of all is to decide which words in the document
should be indexed - ie answering the question "what is an English word" -
one solution is to create all know trigrams (ie combination of three
letters in a row)
from all words in the english language and apply this as a filter to recognise
unknown words. There is code to do this in my Erlang book But even this
gives unsatisfactory results. The twitter idea of indexing strings
starting with #
is much easier and yields better results.
One of these years I might break out the full-text indexer from elib1
as a stand-alone
application to make it easier to integrate. A further path than might be worth
investigating would be to make a lucene front-end. The lucene file format is
well documented - one might let some standard jaava of c++ indexing
engine performing the actual indexing and build the necessary index on
disk, and let
Erlang do the queries. This way you'll only have to unpack the disk
data structures
and interpret the results. Thinking out the appropriate disk data structures
for a full-tet index is not easy. If you want to index several GBytes
of data you will
not be able to work in-memory and a lot of thought has to be given to
how to cache
things in memory an avoid unnecessary disk reads and writes. This has
been studied for
years. I'm a great fan of reinventing the wheel but reading "Managing Gigbytes"
will give a lot of insights into how to do this.
Cheers
/Joe
On Fri, Sep 23, 2011 at 6:19 PM, Oleg Chernyh <erlang@udaff.com> wrote:
> I'm writing a forum engine that can sustain high amount of users making
> queries at the same time.
> I'm using a KV storage that stores erlang entities which is the way to kill
> overheads and make data accessible really fast (if we know the key, ofc).
> The problem I'm facing is full-text search, as you might guess.
> I don't really want to use any external indexers or databases because I want
> that piece of software to be scalable node-wise and don't want to add any
> more data storage entites to the system to prevent data duplication and to
> ensure consistency.
> So what I want to do is to "invent bicycle" by implementing a full text
> search on a key-value storage.
>
> Here I'll outline my plan for writing that feature and I'd be happy to hear
> criticism.
>
> A simplistic way to think of a full text search engine is a strict text
> search engine, when the result of a search is a list of messages (posts)
> that contain full search keywords (if we search for "abc" only "abc" words
> are matched, so that "abcd" won't match).
> In order to accomplish that I can think of the following things to do:
> 1) We make a set of all words W
> 2) For each w \in W we have an "index" I_w which returns a list of all posts
> that contain w
>
> When we add a pure full text search functionality (indeed, we might want
> "geology" to match "geologist") we do the following:
> 1) make a set of normalized words W_n
> 2) make a set of common prefixes P
> 3) make a set of common suffixes S
> 4) define a normalization function f that strips common suffixes and
> prefixes from a word
> 5) define a matching function m that maps f(w) to a list of words from the
> W_n set
> 5.1)
> 6) for each w in W_n we keep an "index" W_n that returns all the messages M
> for which \exists x \in M : m(f(x)) = w
> 7) for each word m in new message
>
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@erlang.org
> http://erlang.org/mailman/listinfo/erlang-questions
>
_______________________________________________
erlang-questions mailing list
erlang-questions@erlang.org
http://erlang.org/mailman/listinfo/erlang-questions
Post received from mailinglist |
|
|
| Back to top |
|
| krestenkrab |
Posted: Mon Sep 26, 2011 5:59 pm |
|
|
|
Joined: 02 May 2010
Posts: 7
|
You should take a look at https://github.com/basho/merge_index
Kresten
On 23/09/2011, at 18.20, "Oleg Chernyh" <erlang@udaff.com> wrote:
> I'm writing a forum engine that can sustain high amount of users
> making queries at the same time.
> I'm using a KV storage that stores erlang entities which is the way to
> kill overheads and make data accessible really fast (if we know the
> key, ofc).
> The problem I'm facing is full-text search, as you might guess.
> I don't really want to use any external indexers or databases because
> I want that piece of software to be scalable node-wise and don't want
> to add any more data storage entites to the system to prevent data
> duplication and to ensure consistency.
> So what I want to do is to "invent bicycle" by implementing a full
> text search on a key-value storage.
>
> Here I'll outline my plan for writing that feature and I'd be happy to
> hear criticism.
>
> A simplistic way to think of a full text search engine is a strict
> text search engine, when the result of a search is a list of messages
> (posts) that contain full search keywords (if we search for "abc" only
> "abc" words are matched, so that "abcd" won't match).
> In order to accomplish that I can think of the following things to do:
> 1) We make a set of all words W
> 2) For each w \in W we have an "index" I_w which returns a list of all
> posts that contain w
>
> When we add a pure full text search functionality (indeed, we might
> want "geology" to match "geologist") we do the following:
> 1) make a set of normalized words W_n
> 2) make a set of common prefixes P
> 3) make a set of common suffixes S
> 4) define a normalization function f that strips common suffixes and
> prefixes from a word
> 5) define a matching function m that maps f(w) to a list of words from
> the W_n set
> 5.1)
> 6) for each w in W_n we keep an "index" W_n that returns all the
> messages M for which \exists x \in M : m(f(x)) = w
> 7) for each word m in new message
>
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@erlang.org
> http://erlang.org/mailman/listinfo/erlang-questions
_______________________________________________
erlang-questions mailing list
erlang-questions@erlang.org
http://erlang.org/mailman/listinfo/erlang-questions
Post received from mailinglist |
|
|
| Back to top |
|
| wuji |
Posted: Sat Sep 15, 2012 4:55 am |
|
|
|
User
Joined: 10 Aug 2012
Posts: 654
|
guy, how do I get in contact with him?'"Click Here for the the designer replica *beep* the Blotter Homepage. Ellen DeGeneres Reflects on Coming-Out Episode, 15 Years LaterTalk
Host Says She Worried Audience Wouldn't Applaud or Like HerBy BRINDA ADHIKARI ADHIKARI [h1]cheap authentic air jordans[/h1] ADHIKARI and ENJOLI FRANCISMay 4, 2012 Ellen DeGeneres is a powerhouse
these days, associated with a successful talk show, awards shows and talent talent [h1]discount designer *beep*[/h1] talent competitions as well as a serious love for dancing -- something
even shared with President Obama.But 15 years ago, on ABC's "20/20" in in discount designer *beep* in April 1997, days before the airing of the episode in which
announced that she was gay, the funny, kind, brave and huge star star cheap real jordans star of her own show shared her fears of coming out."If they
out I was gay, maybe they wouldn't applaud," she said. "Maybe they they cheap authentic air jordans they wouldn't laugh. Maybe they wouldn't like me if they knew that
was gay."During that April 30, 1997 episode of "The Ellen Show" -- -- cheap real jordans -- called "The Puppy Episode" -- DeGeneres sat across from her psychiatrist, |
|
|
| Back to top |
|
|
|
All times are GMT
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You cannot download files in this forum
|
|
|