Logo Search packages:      
Sourcecode: pan version File versions

const Article * DataImpl::xover_add ( const Quark server,
const Quark group,
const StringView subject,
const StringView author,
const StringView time,
const StringView message_id,
const StringView references,
const unsigned long  byte_count,
const unsigned long  line_count,
const StringView xref 
) [virtual]

A new header to add to a group. This must be called inside an xover_ref() / xover_unref() block.

If a new article was created -- as opposed to a new part being added to an existing article -- then a pointer to the new article is returned.

FIXME: this return value is kind of odd, and is just there to suit task-xover's needs.

Implements pan::Data.

Definition at line 224 of file xover.cc.

References pan::DataImpl::XOverEntry::_added_batch, pan::DataImpl::XOverEntry::_batch_parts_size, pan::DataImpl::XOverEntry::_changed_batch, pan::DataImpl::XOverEntry::_subject_lookup, pan::Article::author, pan::Article::Part::bytes, pan::StringView::empty(), pan::Quark::empty(), pan::Xref::insert(), pan::Article::is_binary, load_article(), load_part(), pan::Article::message_id, pan::Article::score, pan::ArticleFilter::score_article(), pan::DataImpl::XOverEntry::score_sections, pan::Article::Part::set_message_id(), pan::Article::set_part_count(), pan::StringView::str, pan::Article::subject, pan::Article::time_posted, pan::StringView::trim(), xover_get_workarea(), and pan::Article::xref.

{
  const Article* new_article (0);
  GroupHeaders * h (get_group_headers (group));
  h->_dirty = true;
  XOverEntry& workarea (xover_get_workarea (group));
  const std::string references (
    GNKSA :: remove_broken_message_ids_from_references (references_in));

  /***
  **** Multipart Handling
  ***/

  int part_index, part_count;
  std::string multipart_subject;
  find_parts (subject, group, line_count, part_index, part_count, multipart_subject);
  Quark art_mid;

  if (part_count > 1)
  {
    StringView ref(references), parent;
    ref.pop_last_token (parent, ' ');
    parent.trim ();

    typedef XOverEntry::subject_to_mid_t::const_iterator cit;
    const std::pair<cit,cit> range (workarea._subject_lookup.equal_range (multipart_subject));
    for (cit it(range.first), end(range.second); it!=end && art_mid.empty(); ++it) {
      const Quark& candidate_mid (it->second);
      const Article* candidate (h->find_article (candidate_mid));
      if (candidate
          && (candidate->author == author)
          && ((int)candidate->parts.size() == part_count)
          && (h->find_parent_message_id(candidate->message_id) == parent))
        art_mid = candidate_mid;
    }
  }

  if (art_mid.empty())
  {
    art_mid = message_id;

    if (part_count > 1)
      workarea._subject_lookup.insert(std::pair<Quark,Quark>(multipart_subject, art_mid));

    // if we don't already have this article...
    if (!h->find_article (art_mid))
    {
      //std::cerr << LINE_ID << " We didn't have this article yet, so creating an instance..." << std::endl;
      Article& a (h->alloc_new_article());
      a.author = author;
      a.subject = multipart_subject;
      a.message_id = art_mid;
      a.is_binary = part_count >= 1;
      a.set_part_count (a.is_binary ? part_count : 1);
      a.time_posted = time_posted.empty() ? 0 : g_mime_utils_header_decode_date (time_posted.str, NULL);
      a.xref.insert (server, xref);
      load_article (group, &a, references);
      a.score = _article_filter.score_article (*this, workarea.score_sections, group, a); // score _after_ threading
      new_article = &a;

      workarea._added_batch.insert (art_mid);
    }
  }

  /**
  ***  Add the article's part info
  **/

  {
    const int number (part_count<2 ? 1 : part_index);
    Article::Part part;
    part.bytes = byte_count;
    part.set_message_id (art_mid, message_id);
    load_part (group, art_mid, number, line_count, part);
  }

  ++workarea._batch_parts_size;

  if (!workarea._added_batch.count(art_mid))
    workarea._changed_batch.insert(art_mid);

  /**
  ***  Maybe flush the batched changes
  **/

  if (workarea._batch_parts_size >= 5000)
  //if (workarea._batch_parts_size >= 100) // torture test
  {
    on_articles_added (group, workarea._added_batch);
    workarea._added_batch.clear();
    on_articles_changed (workarea._changed_batch, true);
    workarea._changed_batch.clear();
    workarea._batch_parts_size = 0;
  }

  return new_article;
}


Generated by  Doxygen 1.6.0   Back to index