Open Bug 424160 Opened 14 years ago Updated 11 days ago

tags should not be bookmarks folders, move them to a separate table


(Toolkit :: Places, defect, P2)





(Reporter: mak, Unassigned)


(Depends on 2 open bugs, Blocks 20 open bugs)


(Keywords: perf)

i think we should asap move tags to a separate table. Ideally (imo) that should be  like this:

    rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
        "CREATE TABLE moz_tags ("
        "tag TEXT UNIQUE, "
        "lastModified INTEGER)"));
    NS_ENSURE_SUCCESS(rv, rv);

    rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
        "CREATE TABLE moz_tags_relation ("
        "tag_id INTEGER, "
        "item_id INTEGER)"));
    NS_ENSURE_SUCCESS(rv, rv);

why this, actual system cons:

- tags as folders are duplicating data into bookmarks table and that is not good, a good db impl should always avoid duplicating data

- data duplication can bring to problems, since you have to sync things

- data duplication makes table bigger, thus slowing down ALL queries and indexes onto that table. So you have 100 bookmarks, a user set up 10 tags per bookmark, you end up with a 1100 records table, without having so much useful data added. all those new records has to be skipped or searched by bookmarks queries

- actually we don't know which bookmark has generated a tag, our tags are url-centric, and when we modify a tagged bookmark we don't know what to sync and what to show

- tag queries are generally slower, if you want to generate a tag cloud you end up with some complex and slow query

as a pro the current system has that we can use bookmark functions to manage folders and roots

The new system would require specialized methods, they could be in nsNavBookmarks similar to keyword methods, so GetTagForURI, SetTagForURI, RemoveTagFromURI (or for  Item), or we could refactor TagsService to use queries and manage them by itself.
Cleanup could be done by triggers and expiration.
Migration is quite easy (i already have code to migrate old tags)

Changing from old to new system should not be too complex, that is because mainly where we use tags we use queries, so querying one table or the other should not make big differences. 
You can easily (and fast) get list of tags, number of bookmarks for a tag, bookmark ids for a tag, tags for a bookmark id. You don't have dupes, you don't duplicate data, you extract a list of REAL bookmark ids that you can edit in the UI and changes are system-wide, you're changing the real bookmark.

So even if this is a rewrite that should be done for 3.1, i fear that when 3.0 will be ready users will start using tags (and creating extensions on tags) and our migration work will be more difficult and complex (a regression there could cause dataloss in a release product).

Changing this could be done with some effort for RC1, being protected by the beta status, and that would:
- create a more solid base for future tag changes / extensions
- would make bookmark queries faster (when user will add more tags)
- would make tag queries faster
- would help solving problems with empty or wrong titles (bug 415113, 
- could help mitigating loops problems (bug 400448)
- would solve conflicting names (unique index on tag name)(bug 412655)
- setting/editing tags for a bunch of bookmarks would become changing some index in a simple relation table (bug 412002)
- autocomplete could be faster when querying tags (bug 415960)
- GROUP_CONCAT in awesomebar could be faster
- could help solving duplicated items (bug 402799)
- drag&drop into a tag becomes setting an index into a table
- implementing count would be fast (bug 399260)

So, ideas about this?

First answer would probably be "no, we are too late for taking this change", but that would require adding some method to nsNavBookmarks, revisiting tagginservice and some query. Biggest problem could be frontend moving between tags, but since we already have problems and we are moving to use queries for all tag containers in the frontend...
forgot, blocker bug 419731 could disappear if we are going to use real bookmarks instead of copies..
Blocks: 488968
Summary: Investigate moving tags to a separate table → tags should not be bookmarks folders, move them so a separate table
Bug 451915 - move Firefox/Places bugs to Firefox/Bookmarks and History. Remove all bugspam from this move by filtering for the string "places-to-b-and-h".

In Thunderbird 3.0b, you do that as follows:
Tools | Message Filters
Make sure the correct account is selected. Click "New"
Conditions: Body   contains   places-to-b-and-h
Change the action to "Delete Message".
Select "Manually Run" from the dropdown at the top.
Click OK.

Select the filter in the list, make sure "Inbox" is selected at the bottom, and click "Run Now". This should delete all the bugspam. You can then delete the filter.

Component: Places → Bookmarks & History
QA Contact: places → bookmarks
Depends on: 653816
Blocks: 701145
Summary: tags should not be bookmarks folders, move them so a separate table → tags should not be bookmarks folders, move them to a separate table
Blocks: 468307
Blocks: 386396
Flags: firefox-backlog+
Blocks: PlacesDiet
Depends on: 1017502
Whiteboard: p=13
Points: --- → 13
Flags: qe-verify?
Whiteboard: p=13
Assignee: nobody → althaf.mozilla
Mentor: mak77
So, this is a first possible solution that can be extended to multiple tags. Unfortunately there's no clean way to bind an IN construct, and doing that manually could introduce SQL injection. so maybe better to use a for loop and manually add "where "
  "tag = ? OR "
and then bind in another loop.

SELECT id, url FROM moz_places h
JOIN tags_relation r ON place_id =
JOIN tags t ON t.tag_id = r.tag_id
WHERE tag IN ("one", "two")
HAVING count(*) = 2
Flags: needinfo?(althaf.mozilla)
please also note I'm adding a Sqlite.wrapStorageConnection in bug 1068620.
Depends on: 1039200
Hi althaf, do you have any news?
Anyway I can help?
I'm making an addon that's stuck on this "bug". So I'm prepared to help.
I'm just a beginner at ECMA 6 and Firefox code, but I can code a lot and let someone review it.
Never helped source code of firefox itself though, so I would need some link on how to help (and some status of where you guys are at in this issue.)
Hey mak.
Sorry for the really late reply, and general disappearance, got just caught up in other things.
If ORUBn0 wants to take over, feel free to do so.
Flags: needinfo?(althaf.mozilla)
(In reply to Althaf Hameez [:ahameez] from comment #7)
> Sorry for the really late reply, and general disappearance, got just caught
> up in other things.

I figured that :)

(In reply to 0RUBn0 from comment #6)
> Never helped source code of firefox itself though, so I would need some link
> on how to help (and some status of where you guys are at in this issue.)

you can likely start from have a build system setup and ready, understand how to import and modify patches.

Then you could maybe start with bug 653816, where we can change and deprecate the  GetBookmarkIdsForURI method.
Then Althaf's patches in bug 1039200 should be unbitrotted, the pending feedback comments should be applied. From there on the plan is explained in
Blocks: 1172828
Blocks: 1175888
After some reading and addon-developing, including some native source diving, I think my expertise is much too low to help you with this, especially as it looks that this has all to be done in one go, seeing how often and quick bookmarks/tags code change in the current system already...
I'll think about it when I could find some time. I'm a teacher, so my "holidays" are over and it could take a year or more. Just saying. 
Sorry, because I would really have helped.
Priority: -- → P1
Priority: P1 → P2
Keywords: perf
Assignee: althaf.mozilla → nobody
Blocks: 503940
Depends on: 1293445
Component: Bookmarks & History → Places
Product: Firefox → Toolkit
Mentor: mak77
Blocks: 1440260
Blocks: 1440988
Blocks: 1083465
Blocks: 1441695
Blocks: 1441697
Blocks: 1441698
No longer blocks: 1083465
Blocks: 1441702
Blocks: 1012834
Depends on: 1448885
Blocks: 1225916
Blocks: 1396364
Blocks: 1176346
No longer blocks: 503940
Blocks: 1473530
Blocks: 1475582
Blocks: 1499343
Depends on: 1607248
Blocks: 1636755
Depends on: 1678607
No longer blocks: 1473530
Blocks: 1734048
You need to log in before you can comment on or make changes to this bug.