Of message history, and the thing that powers it
Adium has a feature called “message history”. When you open a new chat with a person, message history shows you the last n messages from your previous chat with that person, to remind you of the discussion from last time. This feature underwent some major changes in Adium 1.0.
Storage
Before Adium 1.0, Adium wrote those last n messages to a plist file when the chat closed. The problem with that was that when Adium crashed, the plist file would not be written out. This meant that when the user reopened the chat, the user would often be alarmed to find that the chat he had just been in (when he crashed) was not reflected in the message history, and would then conclude that the log of that chat had been lost.
This was never the case—we’ve always updated the log as messages are received and sent, never deferring writing to the end of the chat. But the confusion is understandable.
In Adium 1.0, we did away with the separate plist storage; we now use the logs (now called transcripts) for message history. This prevents the “where’d my history go?” problem, and ends the redundancy of writing out messages once to the logs and again to the plist.
Format
Before Adium 1.0, Adium stored its logs in a faux-HTML format. It was sufficient for display, and moderately parseable, but it was not very extensible, and not a true log format unto itself. (This is the format that Chat Transcript Manager understands.)
In Adium 1.0, we switched to a new real transcript format, which we call Unified Logging Format, and which is based on XML.
The problem now was how to quickly retrieve the last n messages from an XML transcript for the purpose of displaying the message history.
We had two options:
-
Solution A: Use an existing XML parser to read the entire transcript, ignoring all messages except the last n.
This solution doesn’t scale. A large transcript would cause a noticeable delay in opening a chat. This would be especially bad for chats opened from the remote side, since the user would not expect the beachball that would appear while Adium loads all those messages, discarding most of them on its way to the last n.
-
Solution B: Write a new parser that parses the XML data in reverse.
Solution B is what I did.
I named the new parser “LMX” because it parses XML backwards (get it?). This allows Adium to read the last n without reading any of the messages before them.