Ticket #250: patch_kan_ru.patch

File patch_kan_ru.patch, 7.3 KB (added by Richard Boulton, 14 years ago)

Cleaned up version of Kan-Ru Chen's patch

  • backends/flint/flint_database.cc

     
    12781278        }
    12791279 
    12801280        if (!modifying || document.internal->terms_modified()) {
    1281             // FIXME - in the case where there is overlap between the new
    1282             // termlist and the old termlist, it would be better to compare the
    1283             // two lists, and make the minimum set of modifications required.
    1284             // This would lead to smaller changesets for replication, and
    1285             // probably be faster overall.
    1286 
    1287             // First, add entries to remove the postings in the underlying record.
    12881281            Xapian::Internal::RefCntPtr<const FlintWritableDatabase> ptrtothis(this);
    12891282            FlintTermList termlist(ptrtothis, did);
     1283            Xapian::TermIterator term = document.termlist_begin();
     1284            Xapian::TermIterator term_end = document.termlist_end();
     1285            flint_doclen_t new_doclen = termlist.get_doclength();
     1286            string old_tname, new_tname;
    12901287
     1288            total_length -= new_doclen;
     1289
    12911290            termlist.next();
    1292             while (!termlist.at_end()) {
    1293                 string tname = termlist.get_termname();
    1294                 termcount wdf = termlist.get_wdf();
     1291            while (true) {
     1292                bool identical = false;
     1293                int cmp;
     1294                if (termlist.at_end() && term == term_end)
     1295                    break;
     1296                if (!termlist.at_end() && term != term_end) {
     1297                    old_tname = termlist.get_termname();
     1298                    new_tname = *term;
     1299                    cmp = old_tname.compare(new_tname);
    12951300
    1296                 map<string, pair<termcount_diff, termcount_diff> >::iterator i;
    1297                 i = freq_deltas.find(tname);
    1298                 if (i == freq_deltas.end()) {
    1299                     freq_deltas.insert(make_pair(tname, make_pair(-1, -termcount_diff(wdf))));
     1301                    // Check postlist to see whether they are identical
     1302                    if (cmp == 0) {
     1303                        int new_count = term.positionlist_count();
     1304                        int old_count = termlist.positionlist_count();
     1305                        if (old_count == new_count) {
     1306                            PositionIterator it = term.positionlist_begin();
     1307                            PositionIterator it_end = term.positionlist_end();
     1308                            PositionIterator old = termlist.positionlist_begin();
     1309                            if (equal(it, it_end, old))
     1310                                identical = true;
     1311                        }
     1312                    }
     1313                } else if (termlist.at_end()) {
     1314                    cmp = 2;
     1315                    new_tname = *term;
    13001316                } else {
    1301                     --i->second.first;
    1302                     i->second.second -= wdf;
     1317                    cmp = -2;
     1318                    old_tname = termlist.get_termname();
    13031319                }
    13041320
    1305                 // Remove did from tname's postlist
    1306                 map<string, map<docid, pair<char, termcount> > >::iterator j;
    1307                 j = mod_plists.find(tname);
    1308                 if (j == mod_plists.end()) {
    1309                     map<docid, pair<char, termcount> > m;
    1310                     j = mod_plists.insert(make_pair(tname, m)).first;
    1311                 }
     1321                if (cmp < 0) {
     1322                    const string& tname = old_tname;
     1323                    termcount wdf = termlist.get_wdf();
     1324                    new_doclen -= wdf;
    13121325
    1313                 map<docid, pair<char, termcount> >::iterator k;
    1314                 k = j->second.find(did);
    1315                 if (k == j->second.end()) {
    1316                     j->second.insert(make_pair(did, make_pair('D', 0u)));
    1317                 } else {
    1318                     // Modifying a document we added/modified since the last flush.
    1319                     k->second = make_pair('D', 0u);
    1320                 }
     1326                    map<string, pair<termcount_diff, termcount_diff> >::iterator i;
     1327                    i = freq_deltas.find(tname);
     1328                    if (i == freq_deltas.end()) {
     1329                        freq_deltas.insert(make_pair(tname, make_pair(-1, -termcount_diff(wdf))));
     1330                    } else {
     1331                        --i->second.first;
     1332                        i->second.second -= wdf;
     1333                    }
    13211334
    1322                 termlist.next();
    1323             }
     1335                    // Remove did from tname's postlist
     1336                    map<string, map<docid, pair<char, termcount> > >::iterator j;
     1337                    j = mod_plists.find(tname);
     1338                    if (j == mod_plists.end()) {
     1339                        map<docid, pair<char, termcount> > m;
     1340                        j = mod_plists.insert(make_pair(tname, m)).first;
     1341                    }
    13241342
    1325             total_length -= termlist.get_doclength();
     1343                    map<docid, pair<char, termcount> >::iterator k;
     1344                    k = j->second.find(did);
     1345                    if (k == j->second.end()) {
     1346                        j->second.insert(make_pair(did, make_pair('D', 0u)));
     1347                    } else {
     1348                        // Modifying a document we added/modified since the last flush.
     1349                        k->second = make_pair('D', 0u);
     1350                    }
     1351                } else if (!identical) {
     1352                    const string& tname = new_tname;
     1353                    termcount wdf = term.get_wdf();
     1354                    new_doclen += wdf;
    13261355
    1327             flint_doclen_t new_doclen = 0;
    1328             Xapian::TermIterator term = document.termlist_begin();
    1329             Xapian::TermIterator term_end = document.termlist_end();
    1330             for ( ; term != term_end; ++term) {
    1331                 // Calculate the new document length
    1332                 termcount wdf = term.get_wdf();
    1333                 new_doclen += wdf;
     1356                    if (cmp > 0) {
     1357                        if (tname.size() > MAX_SAFE_TERM_LENGTH)
     1358                            throw Xapian::InvalidArgumentError("Term too long (> "STRINGIZE(MAX_SAFE_TERM_LENGTH)"): " + tname);
     1359                        map<string, pair<termcount_diff, termcount_diff> >::iterator i;
     1360                        i = freq_deltas.find(tname);
     1361                        if (i == freq_deltas.end()) {
     1362                            freq_deltas.insert(make_pair(tname, make_pair(1, termcount_diff(wdf))));
     1363                        } else {
     1364                            ++i->second.first;
     1365                            i->second.second += wdf;
     1366                        }
    13341367
    1335                 string tname = *term;
    1336                 if (tname.size() > MAX_SAFE_TERM_LENGTH)
    1337                     throw Xapian::InvalidArgumentError("Term too long (> "STRINGIZE(MAX_SAFE_TERM_LENGTH)"): " + tname);
    1338                 map<string, pair<termcount_diff, termcount_diff> >::iterator i;
    1339                 i = freq_deltas.find(tname);
    1340                 if (i == freq_deltas.end()) {
    1341                     freq_deltas.insert(make_pair(tname, make_pair(1, termcount_diff(wdf))));
    1342                 } else {
    1343                     ++i->second.first;
    1344                     i->second.second += wdf;
    1345                 }
     1368                        // Add did to tname's postlist
     1369                        map<string, map<docid, pair<char, termcount> > >::iterator j;
     1370                        j = mod_plists.find(tname);
     1371                        if (j == mod_plists.end()) {
     1372                            map<docid, pair<char, termcount> > m;
     1373                            j = mod_plists.insert(make_pair(tname, m)).first;
     1374                        }
     1375                        map<docid, pair<char, termcount> >::iterator k;
     1376                        k = j->second.find(did);
     1377                        if (k != j->second.end()) {
     1378                            Assert(k->second.first == 'D');
     1379                            k->second.first = 'M';
     1380                            k->second.second = wdf;
     1381                        } else {
     1382                            j->second.insert(make_pair(did, make_pair('A', wdf)));
     1383                        }
     1384                    }
    13461385
    1347                 // Add did to tname's postlist
    1348                 map<string, map<docid, pair<char, termcount> > >::iterator j;
    1349                 j = mod_plists.find(tname);
    1350                 if (j == mod_plists.end()) {
    1351                     map<docid, pair<char, termcount> > m;
    1352                     j = mod_plists.insert(make_pair(tname, m)).first;
     1386                    PositionIterator it = term.positionlist_begin();
     1387                    PositionIterator it_end = term.positionlist_end();
     1388                    if (it != it_end) {
     1389                        position_table.set_positionlist(
     1390                                                        did, tname, it, it_end);
     1391                    } else {
     1392                        position_table.delete_positionlist(did, tname);
     1393                    }
    13531394                }
    1354                 map<docid, pair<char, termcount> >::iterator k;
    1355                 k = j->second.find(did);
    1356                 if (k != j->second.end()) {
    1357                     Assert(k->second.first == 'D');
    1358                     k->second.first = 'M';
    1359                     k->second.second = wdf;
    1360                 } else {
    1361                     j->second.insert(make_pair(did, make_pair('A', wdf)));
     1395                if (termlist.at_end())
     1396                    ++term;
     1397                else if (term == term_end)
     1398                    termlist.next();
     1399                else {
     1400                    if (cmp >= 0)
     1401                        ++term;
     1402                    if (cmp <= 0)
     1403                        termlist.next();
    13621404                }
     1405            }
    13631406
    1364                 PositionIterator it = term.positionlist_begin();
    1365                 PositionIterator it_end = term.positionlist_end();
    1366                 if (it != it_end) {
    1367                     position_table.set_positionlist(
    1368                         did, tname, it, it_end);
    1369                 } else {
    1370                     position_table.delete_positionlist(did, tname);
    1371                 }
    1372             }
    13731407            LOGLINE(DB, "Calculated doclen for replacement document " << did << " as " << new_doclen);
    13741408
    13751409            // Set the termlist