search.cc
上传用户:psq1974
上传日期:2007-01-06
资源大小:1195k
文件大小:4k
源码类别:

mpeg/mp3

开发平台:

C/C++

  1. /* Copyright (C) 1998, 1999 State University of New York at Stony Brook
  2.    Author: Andrew V. Shuvalov ( andrew@ecsl.cs.sunysb.edu )
  3.    Software license is located in file "COPYING"
  4. */
  5. #include "search.h"
  6. int BoolSearchOperation::precedence() const
  7. {
  8.   return precedence( get_type() );
  9. }
  10. int BoolSearchOperation::precedence( SearchItem::type type )
  11. {
  12.   switch( type )
  13.     {
  14.     case SearchItem::result:
  15.       return 3;
  16.     case SearchItem::and:
  17.     case SearchItem::andnot:
  18.       return 2;
  19.     case SearchItem::or:
  20.     case SearchItem::resultand:
  21.     case SearchItem::resultandnot:
  22.       return 1;
  23.     default:
  24.       return 1;
  25.     }
  26. }
  27. BoolSearchOperation *BoolSearchOperation::create_by_childs_and_item
  28. ( BoolSearchOperation *leftchild, BoolSearchOperation *rightchild, 
  29.   const SearchItem &item ) const
  30. {
  31.   BoolSearchOperation *node = NULL;
  32.   switch( item.get_type() )
  33.     {
  34.     case SearchItem::and:
  35.     case SearchItem::resultand:
  36.       node = new BoolSearchOperationAnd( wordDb );
  37.       break;
  38.     case SearchItem::andnot:
  39.     case SearchItem::resultandnot:
  40.       node = new BoolSearchOperationAndNot( wordDb );
  41.       break;
  42.     case SearchItem::or:
  43.       node = new BoolSearchOperationOr( wordDb );
  44.       break;
  45.     case SearchItem::err:
  46.     default:
  47.       throw GeneralException( "Unsupported bool operation" );
  48.     }
  49.   if( node )
  50.     node->left = leftchild;
  51.   else
  52.     throw GeneralException( "Bool operation error" );
  53.   node->right = rightchild;
  54.   
  55.   return node;
  56. }
  57. // static:
  58. BoolSearchOperation *BoolSearchOperation::merge_search_items
  59. ( BoolSearchOperation *head, BoolSearchOperation *right,
  60.   const SearchItem &item )
  61. {
  62.   SearchItem::type type = item.get_type();
  63.   int precedence = head->precedence( type );
  64.   
  65.   if( precedence <= head->precedence() )
  66.     {
  67.       // for example, 'or' is less than 'and', so head with operation 'and'
  68.       // becomes the left child of new 'or' head
  69.       
  70.       BoolSearchOperation *newhead = head->create_by_childs_and_item
  71. ( head, right, item );
  72.       return newhead;
  73.     }
  74.   else
  75.     {
  76.       // for example we got 'and' after 'or' as the head. 'and' should be 
  77.       // propagated to the right child. Recursion
  78.       head->right = merge_search_items( head->right, right, item );
  79.       return head; // unchanged
  80.     }
  81. }
  82. // ----------------------------------------------------------------------
  83. const WordOccurencesT &BoolSearchOperationAnd::get_result()
  84. {
  85.   if( left == NULL && right == NULL )
  86.     return WordOccurences;
  87.   if( right == NULL )
  88.     {
  89.       WordOccurences = left->get_result();
  90.       delete left;
  91.       left = NULL;
  92.       return WordOccurences;
  93.     }
  94.   const WordOccurencesT &result_left = left->get_result();
  95.   const WordOccurencesT &result_right = right->get_result();
  96.   WordOccurences = wordDb.merge_and( result_left, result_right );
  97.   // only now we can delete old childs
  98.   delete left;
  99.   left = NULL;
  100.   delete right;
  101.   right = NULL;
  102.   return WordOccurences;
  103. }
  104. // ----------------------------------------------------------------------
  105. const WordOccurencesT &BoolSearchOperationAndNot::get_result()
  106. {
  107.   if( left == NULL && right == NULL )
  108.     return WordOccurences;
  109.   
  110.   if( right == NULL )
  111.     {
  112.       WordOccurences = left->get_result();
  113.       delete left;
  114.       left = NULL;
  115.       return WordOccurences;
  116.     }
  117.   const WordOccurencesT &result_left = left->get_result();
  118.   const WordOccurencesT &result_right = right->get_result();
  119.   WordOccurences = wordDb.merge_and_not( result_left, result_right );
  120.   // only now we can delete old childs
  121.   delete left;
  122.   left = NULL;
  123.   delete right;
  124.   right = NULL;
  125.   return WordOccurences;
  126. }
  127. // ----------------------------------------------------------------------
  128. const WordOccurencesT &BoolSearchOperationOr::get_result()
  129. {
  130.   if( left == NULL && right == NULL )
  131.     return WordOccurences;
  132.   if( right == NULL )
  133.     {
  134.       WordOccurences = left->get_result();
  135.       delete left;
  136.       left = NULL;
  137.       return WordOccurences;
  138.     }
  139.   const WordOccurencesT &result_left = left->get_result();
  140.   const WordOccurencesT &result_right = right->get_result();
  141.   WordOccurences = wordDb.merge_or( result_left, result_right );
  142.   // only now we can delete old childs
  143.   delete left;
  144.   left = NULL;
  145.   delete right;
  146.   right = NULL;
  147.   return WordOccurences;
  148. }