Browse Source

added "cutoff" option to SetLimits()

git-svn-id: svn://svn.sphinxsearch.com/sphinx/trunk@619 406a0c4d-033a-0410-8de8-e80135713968
shodan 19 năm trước cách đây
mục cha
commit
f0a0ec4ed5
4 tập tin đã thay đổi với 47 bổ sung34 xóa
  1. 10 4
      api/sphinxapi.php
  2. 15 2
      src/searchd.cpp
  3. 20 28
      src/sphinx.cpp
  4. 2 0
      src/sphinx.h

+ 10 - 4
api/sphinxapi.php

@@ -23,7 +23,7 @@ define ( "SEARCHD_COMMAND_EXCERPT",	1 );
 define ( "SEARCHD_COMMAND_UPDATE",	2 );
 
 /// current client-side command implementation versions
-define ( "VER_COMMAND_SEARCH",		0x108 );
+define ( "VER_COMMAND_SEARCH",		0x109 );
 define ( "VER_COMMAND_EXCERPT",		0x100 );
 define ( "VER_COMMAND_UPDATE",		0x100 );
 
@@ -77,6 +77,7 @@ class SphinxClient
 	var $_groupfunc;	///< group-by function (to pre-process group-by attribute value with)
 	var $_groupsort;	///< group-by sorting clause (to sort groups in result set with)
 	var $_maxmatches;	///< max matches to retrieve
+	var $_cutoff;		///< cutoff to stop searching at (default is 0)
 
 	var $_error;		///< last error message
 	var $_warning;		///< last warning message
@@ -103,6 +104,7 @@ class SphinxClient
 		$this->_groupfunc	= SPH_GROUPBY_DAY;
 		$this->_groupsort	= "@group desc";
 		$this->_maxmatches	= 1000;
+		$this->_cutoff		= 0;
 
 		$this->_error	= "";
 		$this->_warning	= "";
@@ -220,8 +222,9 @@ class SphinxClient
 	// searching
 	/////////////////////////////////////////////////////////////////////////////
 
-	/// set match offset, count, and max number to retrieve
-	function SetLimits ( $offset, $limit, $max=0 )
+	/// set offset and count into result set,
+	/// and max-matches and cutoff to use while searching
+	function SetLimits ( $offset, $limit, $max=0, $cutoff=0 )
 	{
 		assert ( is_int($offset) );
 		assert ( is_int($limit) );
@@ -232,6 +235,8 @@ class SphinxClient
 		$this->_limit = $limit;
 		if ( $max>0 )
 			$this->_maxmatches = $max;
+		if ( $cutoff>0 )
+			$this->_cutoff = $cutoff;
 	}
 
 	/// set match mode
@@ -418,10 +423,11 @@ class SphinxClient
 			$req .= pack ( "N", $filter["exclude"] );
 		}
 
-		// group-by, max matches, sort-by-group flag
+		// group-by clause, max-matches count, group-sort clause, cutoff count
 		$req .= pack ( "NN", $this->_groupfunc, strlen($this->_groupby) ) . $this->_groupby;
 		$req .= pack ( "N", $this->_maxmatches );
 		$req .= pack ( "N", strlen($this->_groupsort) ) . $this->_groupsort;
+		$req .= pack ( "N", $this->_cutoff );
 
 		////////////////////////////
 		// send query, get response

+ 15 - 2
src/searchd.cpp

@@ -180,7 +180,7 @@ enum SearchdCommand_e
 /// known command versions
 enum
 {
-	VER_COMMAND_SEARCH		= 0x108,
+	VER_COMMAND_SEARCH		= 0x109,
 	VER_COMMAND_EXCERPT		= 0x100,
 	VER_COMMAND_UPDATE		= 0x100
 };
@@ -1532,7 +1532,7 @@ int QueryRemoteAgents ( const char * sIndexName, DistributedIndex_t & tDist, con
 				}
 
 				// do query!
-				int iReqSize = 68 + 2*sizeof(SphDocID_t) + 4*tQuery.m_iWeights
+				int iReqSize = 72 + 2*sizeof(SphDocID_t) + 4*tQuery.m_iWeights
 					+ strlen ( tQuery.m_sSortBy.cstr() )
 					+ strlen ( tQuery.m_sQuery.cstr() )
 					+ strlen ( tAgent.m_sIndexes.cstr() )
@@ -1590,6 +1590,7 @@ int QueryRemoteAgents ( const char * sIndexName, DistributedIndex_t & tDist, con
 				tOut.SendString ( tQuery.m_sGroupBy.cstr() );
 				tOut.SendInt ( tQuery.m_iMaxMatches );
 				tOut.SendString ( tQuery.m_sGroupSortBy.cstr() );
+				tOut.SendInt ( tQuery.m_iCutoff );
 				tOut.Flush ();
 
 				// FIXME! handle flush failure
@@ -2347,7 +2348,14 @@ void HandleCommandSearch ( int iSock, int iVer, InputBuffer_c & tReq )
 		}
 	}
 
+	// v.1.9
+	if ( iVer>=0x109 )
+		tQuery.m_iCutoff = tReq.GetInt();
+
+	/////////////////////
 	// additional checks
+	/////////////////////
+
 	if ( tReq.GetError() )
 	{
 		tReq.SendErrorReply ( "invalid or truncated request" );
@@ -2380,6 +2388,11 @@ void HandleCommandSearch ( int iSock, int iVer, InputBuffer_c & tReq )
 		tReq.SendErrorReply ( "limit out of bounds (limit=%d)", tQuery.m_iLimit );
 		return;
 	}
+	if ( tQuery.m_iCutoff<0 )
+	{
+		tReq.SendErrorReply ( "cutoff out of bounds (cutoff=%d)", tQuery.m_iCutoff );
+		return;
+	}
 
 	////////////////
 	// do searching

+ 20 - 28
src/sphinx.cpp

@@ -2956,6 +2956,7 @@ CSphQuery::CSphQuery ()
 	, m_sGroupSortBy( "@group desc" )
 	, m_iAttrs		( -1 )
 	, m_iGroupBy	( -1 )
+	, m_iCutoff		( 0 )
 {}
 
 
@@ -6267,6 +6268,17 @@ void CSphIndex_VLN::LookupDocinfo ( CSphDocInfo & tMatch )
 }
 
 
+#define SPH_SUBMIT_MATCH(_match) \
+	if ( bLateLookup ) \
+		LookupDocinfo ( _match ); \
+	\
+	if ( pTop->Push ( _match ) ) \
+		pResult->m_iTotalMatches++; \
+	\
+	if ( pQuery->m_iCutoff>0 && pResult->m_iTotalMatches>=pQuery->m_iCutoff ) \
+		break;
+
+
 void CSphIndex_VLN::MatchAll ( const CSphQuery * pQuery, ISphMatchSorter * pTop, CSphQueryResult * pResult )
 {
 	///////////////////
@@ -6426,16 +6438,8 @@ void CSphIndex_VLN::MatchAll ( const CSphQuery * pQuery, ISphMatchSorter * pTop,
 				tMatch.m_iWeight += m_dWeights[i] * ( matchWeight[i] + phraseWeight[i] );
 		}
 
-		////////////////
-		// submit match
-		////////////////
-
-		// lookup externally stored docinfo
-		if ( bLateLookup )
-			LookupDocinfo ( tMatch );
-
-		if ( pTop->Push ( tMatch ) )
-			pResult->m_iTotalMatches++;
+		// submit
+		SPH_SUBMIT_MATCH ( tMatch );
 
 		// continue looking for next matches
 		i = 0;
@@ -6586,12 +6590,8 @@ void CSphIndex_VLN::MatchAny ( const CSphQuery * pQuery, ISphMatchSorter * pTop,
 		for ( i=0; i<m_iWeights; i++ )
 			tMatch.m_iWeight += m_dWeights[i] * ( sphBitCount(dWeights[i].m_uMatch) + dWeights[i].m_iMaxPhrase*iPhraseK );
 
-		// lookup externally stored docinfo
-		if ( bLateLookup )
-			LookupDocinfo ( tMatch );
-
-		if ( pTop->Push ( tMatch ) )
-			pResult->m_iTotalMatches++;
+		// submit
+		SPH_SUBMIT_MATCH ( tMatch );
 	}
 }
 
@@ -6879,12 +6879,8 @@ bool CSphIndex_VLN::MatchBoolean ( const CSphQuery * pQuery, CSphDict * pDict, I
 		// set weight and push it to the queue
 		pMatch->m_iWeight = 1; // set weight
 
-		// lookup externally stored docinfo
-		if ( bLateLookup )
-			LookupDocinfo ( *pMatch );
-
-		if ( pTop->Push ( *pMatch ) )
-			pResult->m_iTotalMatches++;
+		// submit
+		SPH_SUBMIT_MATCH ( *pMatch );
 	}
 
 	return true;
@@ -7773,12 +7769,8 @@ bool CSphIndex_VLN::MatchExtended ( const CSphQuery * pQuery, CSphDict * pDict,
 		if ( sphMatchEarlyReject ( *pAccept, pQuery ) )
 			continue;
 
-		// lookup externally stored docinfo
-		if ( bLateLookup )
-			LookupDocinfo ( *pAccept );
-
-		if ( pTop->Push ( *pAccept ) )
-			pResult->m_iTotalMatches++;
+		// submit
+		SPH_SUBMIT_MATCH ( *pAccept );
 	}
 
 	return true;

+ 2 - 0
src/sphinx.h

@@ -971,6 +971,8 @@ public:
 	ESphGroupBy		m_eGroupFunc;	///< function to pre-process group-by attribute value with
 	CSphString		m_sGroupSortBy;	///< sorting clause for groups in group-by mode
 
+	int				m_iCutoff;		///< matches count threshold to stop searching at (defualt is 0; means to search until all matches are found)
+
 protected:
 	int				m_iAttrs;		///< attribute count (necessary to instantiate group-by queues)
 	int				m_iGroupBy;		///< group-by attribute index