News for hackers. Stuff that matters.
Re:PG: What's your current take on reddit's comment system? by brett on Thursday July 12, 2007 @03:39PM (#33888)
Incidentally I came across this while trying to find information about how reddit stores threaded comments. I've read they use postgres and while I've also read about many workable techniques to force hierarchical (and frequently reordered) comments into a relational db these solutions all sort of make me cringe. I'd welcome anyone's ideas here as well.
Re:PG: What's your current take on reddit's comment system? by nostrademons on Thursday July 12, 2007 @04:40PM (#33902)
The approach I took on Diffle (http://www.diffle.com/ - unfortunately it hasn't been exercised as we haven't really got traction yet) was to store the comment ID as a varbinary(255). A child comment takes the ID of the parent and then appends a 2-byte sequential number. So, the first comment is 0x0001, the second is 0x0002, a reply to the second is 0x00020001, a second reply is 0x00020002, the third is 0x0003, a reply to the third is 0x00030001, etc. To find the children of a comment, you look for all comments where the parent's ID is a prefix. MySQL can use leftmost-prefixes as indexes, so this computes very quickly. Also, with the standard varbinary collating order, 0x01 sorts before 0x0101, 0x0102, 0x02, etc, so all I have to do is order by the ID and everything will come out in proper threaded order. And nesting depth is calculated easily by len(id) / 2.

Reordering can be done just by looking at all records whose IDs contain the parent as a prefix and have a length 2 greater than the parent, and then renumbering them. This should be computationally feasible in most cases.

This does limit users to 65,536 replies to a single comment, and a maximum comment nesting depth of 127. Based on my experience with some very active LiveJournal threads, I considered these to be acceptable limitations (LJ limits comments to 5000/post anyway). A nesting depth of 127 would be nearly 2400 pixels over, so it's not like it'd all fit on one screen anyway.

Re:PG: What's your current take on reddit's comment system? by vlad on Thursday July 12, 2007 @06:17PM (#33920)
Why not just store the parentid (can be another comment or the news topic), username (instead of userid so you don't have to access the users table), and votecount for each comment?

Also, each comment should have a newsid field that points to the original newstopic. The left-most posts would have the parentid and newsid that were the same (or parentid can be zero, depending on how you do it). But any replies would have the parentid to the parent comment, but the newsid would still point to the newstopic. Then you just run an SQL query to find all comments with the newsid for that newstopic. You won't have to join any tables. After that, with everything in memory, you can just sort the way it has to be. Finally, you can cache the page in memory or a file in case the page doesn't change for the next set of visitors.

Re:PG: What's your current take on reddit's comment system? by nostrademons on Thursday July 12, 2007 @06:29PM (#33923)
How do you get the full thread for a given parent? Selecting based on the parentid alone gives you only immediate descendants. Recursive queries are generally a no-no, as they drag your performance down fairly quickly. Selecting based on the newsid gives you every single comment on the item, and then you'll have to do a lot of work (basically building up the full tree structure in memory) to find out which are children. For a site with traffic like news.yc, it's probably acceptable, but it's still more complicated to code than a simple select.
Re:PG: What's your current take on reddit's comment system? by vlad on Thursday July 12, 2007 @07:13PM (#33926)
You would find the full thread by searching for comments with the appropriate newsid.

To simplify the recursive function (using data in memory, not in the database), you could also have another field, called indent, that stores the level in the comments.

You could find all the comments with one SQL statement (where newsid = news.id), then go through each level of each comment, and sort it that way.

You could even make the parentid field a double, so you would store 123.4 where 123 would be the parent and 4 would be the indentation level.

I guess the difference is, do you want to store everything in one field or have different fields for everything?

I think this gives the original poster many options to think about. To me, a recursive function would be easier to write than coming up with ways to combine multiple fields into one using MySQL.

I think the order of optimization is: 1) Optimize so you can use a cached result if it exists 2) If the cache is out of the date, try to make just one SQL call 3) don't use table joins 4) reorder the data as needed in memory, then save it to a cache

As far as the single SQL call goes, I don't think it matters whether you have 5 fields or 30 in the actual table as long as you only request the fields you need, but I could be wrong.

By the way, do you have any other interesting examples?

Re:PG: What's your current take on reddit's comment system? by clueless on Sunday July 15, 2007 @12:19PM (#34336)
i'm not sure why nobody has said this already... but why would you need an extra filed for keeping indentattion nuber when you can use <pre> in html for that.
Re:PG: What's your current take on reddit's comment system? by nostrademons on Thursday July 12, 2007 @10:08PM (#33956)
Interesting examples of what?
Re:PG: What's your current take on reddit's comment system? by aston on Thursday July 12, 2007 @03:54PM (#33890)
I did a quick and dirty forum a couple years back that now serves up hundreds of new threads a day (having tens, sometimes hundreds of messages each).

My solution was to store a comment thread in display order in the database with hinting as to how deep in the heirarchy the comment is. Optimizes for output, although with some cost every time something gets posted. Luckily, for most forums, views outnumber posts by hundreds of times.

The one issue that system has is that if you're doing a lot of reordering, let's say from quality scores. In that case you'll basically have to remake the thread after every post and after vote that makes a difference. Not recommended...

Re:PG: What's your current take on reddit's comment system? by twism on Thursday July 12, 2007 @03:58PM (#33892)
i am in the process of making a news.yc clone... threaded comments are not as easy as it looks on news.yc.

[edit] especially when the comments get reordered on votes.

Re:PG: What's your current take on reddit's comment system? by aston on Thursday July 12, 2007 @04:00PM (#33895)
If you're trying to mimic this forum with a database solution, it's going to be a pain. PG's keeping this stuff in memory, almost certainly as the tree that it is.

edit on the edit: scratch that.

Re:PG: What's your current take on reddit's comment system? by nostrademons on Thursday July 12, 2007 @05:19PM (#33911)
I mentioned a possible solution here: http://news.ycombinator.com/item?id=33902, but I'm really commenting because there's a really cool connection between PG's approach of storing it as an in-memory tree and my approach of a 2048-bit index:

Y'know how in a typical CS datastructures course you'll have to build a heap, and then reimplement with an array? A heap is conceptually a balanced binary tree where every leaf is filled, while there's nothing tree-like about an array. However, your CS profs were trying to get across that any binary tree can be stored as an array, with the root in position 0, its leaves in positions 1 and 2, their leaves in positions 3, 4, 5, 6, etc. If a node doesn't have a leaf, that position in the array is empty.

Normally this is very inefficient - a totally-unbalanced (linked list) binary tree of length 20 would require a 1MB array to hold it. However, heaps are always perfectly balanced, so an array really is the most efficient implementation for them.

By restricting users to a certain number of replies to each comment (65,536), I'm effectively constraining an arbitrary tree structure to a 65,536-ary tree. Which can then be represented by an array. If held in memory, it'd be a very sparse and inefficient array.

But databases are excellent at storing sparse arrays. If I don't store a potential key, it doesn't take up any space in the DB. And with a good indexing system, I can reference any element in constant time (well, O(logN), but the log base for B-trees is so huge that it might as well be constants).

So, I'm really just applying some of the meta-principles of CS coursework to basic data structures. (Actually, I got the idea off a Slashdot posting and had to figure very little of this out on my own, but it's still really cool.)

Incidentally, there's apparently a deep connection between number systems and tree structures. You can read more about it in Chris Okasaki's Purely Functional Data Structures. Apparently, every number system corresponds to a data structure. For example, Peano arithmetic = linked lists, binary numbers = binary trees, fibonacci numbers = binomial heaps, etc. There's a short presentation on it here: http://www.informatik.uni-bonn.de/~ralf/talks/BCTCS.pdf, and I'd strongly recommend the book.

Re:PG: What's your current take on reddit's comment system? by pg on Thursday July 12, 2007 @06:08PM (#33918)
You probably don't even need to be using the word "bit" unless you're writing something a lot more performance intensive than a forum.
Re:PG: What's your current take on reddit's comment system? by earthboundkid on Saturday July 14, 2007 @11:32PM (#34292)
Optimized ob. quote:

"Premature &#8594; evil."

Re:PG: What's your current take on reddit's comment system? by Jd on Thursday July 12, 2007 @09:54PM (#33952)
Just thinking off the cuff here, but couldn't one store a lisp-style list as a string in a relational database. If I was using Ruby on Rails, I could simply build a simple lisp interpreter in Ruby to parse the string, then capture it as an in-memory tree. This way I would only have active items in memory and could use some of the advantages of the standard web development platforms for whatever else I was doing.

Edit: See Ruby/Lisp for one such already built interpreter.

Re:PG: What's your current take on reddit's comment system? by nostrademons on Thursday July 12, 2007 @10:14PM (#33957)
Sure you could. You could also select all comments on the item and rebuild the tree in-memory, as Vlad suggests elsewhere on this thread. The code isn't even as hard as I'd thought it'd be:

  comments = dbh.query('SELECT * FROM comments WHERE news_id = $newsid')
  response_tree = {}
  for comment in comments:
      comment.children = []
      response_tree[comment.id] = comment
  for comment in comments:
      response_tree[comment.parent_id].children.append(comment)
The nifty thing about storing it in the database is that you need no application-level post-processing, you can take advantage of the DB for ad-hoc queries (what if you want to show subtrees of all posts by a certain user, like the "threads" page here?), and it happens to map to a set of simple and fast operations provided by most databases.
Re:PG: What's your current take on reddit's comment system? by Jd on Thursday July 12, 2007 @11:02PM (#33965)
After some reflection, I suppose my only hesitation with this method is that it locks one into dealing with the comments in a particular way, whereas the lisp model I outlined is easily adaptable to a variety of schemas.

However, I'm not sure how else one would want to model things. Must think more...

Re:PG: What's your current take on reddit's comment system? by twism on Saturday August 18, 2007 @05:17PM (#43889)
This is closely resembles the way i did it... With recurrsive includes (views). Performs flawlessly.
Re:PG: What's your current take on reddit's comment system? by euccastro on Friday July 13, 2007 @03:22PM (#34100)
Why are you using a database, in this case? Aren't you better off serializing your tree using the native methods of your language? (e.g., with pickle.dump() in Python.)
Re:PG: What's your current take on reddit's comment system? by nostrademons on Friday July 13, 2007 @10:17PM (#34156)
Database for searching for by the item (news story, game, journal entry), pickle or sexprs for the individual comment threads. The database helps you manage the hopefully large number of news stories you'll get. The tree takes care of individual comments for a single news story.

Many filesystems have trouble with large numbers of files in a single directory, as you'd get with eg. pickle tree to a file per item.

Re:PG: What's your current take on reddit's comment system? by Jd on Friday July 13, 2007 @11:16PM (#34164)
Is this what you are actually doing? How do you store the pickle output?
Re:PG: What's your current take on reddit's comment system? by nostrademons on Saturday July 14, 2007 @10:28AM (#34209)
I'm not - I'm using the approach here: http://news.ycombinator.com/item?id=33888 . That gives me much more flexibility in picking out individual comments from a thread, returning all comments by a specific user, getting all comments posted today, etc. I'm just recognizing this as another possible way to solve the problem, if you don't care about the extra functionality..

As for storing the pickled output:

  dbh.execute('UPDATE articles SET comments = $comments WHERE news_id = $id', 
              comments=pickle.dumps(article.comments))
The comments field can be a normal TEXT field, since the default format for pickle is ASCII-based.
Re:PG: What's your current take on reddit's comment system? by Jd on Saturday July 14, 2007 @02:36PM (#34234)
Okay, makes sense. I hadn't read your earlier posting that carefully before, but it sounds better than what I had in mind.
Re:PG: What's your current take on reddit's comment system? by Jd on Friday July 13, 2007 @11:15PM (#34163)
The question has to do with storage. I suppose you could serialize it and store in a flat file, but will this beat the DB access time, even if there is extra time needed for interpretation?
Re:PG: What's your current take on reddit's comment system? by euccastro on Friday July 13, 2007 @03:16PM (#34099)
What's hard about threaded comments, exactly?
Re:PG: What's your current take on reddit's comment system? by twism on Saturday July 14, 2007 @11:08AM (#34215)
how you store them, to how they are fetched, to how they are displayed and arranged according to popularity (i think thats how news.yc works) on every vote.