Index: trunk/gsdl/src/mgpp/text/FragLevelConvert.cpp
===================================================================
--- trunk/gsdl/src/mgpp/text/FragLevelConvert.cpp	(revision 926)
+++ trunk/gsdl/src/mgpp/text/FragLevelConvert.cpp	(revision 927)
@@ -86,2 +86,22 @@
 }
 
+
+bool FragLevelConvert::LevelToLevel (FragLevelConvert sectionLevelConvert,
+		 unsigned long levelNum, unsigned long &DocNum) {
+  
+  if (levelNum==1) {
+    DocNum=1;
+    return true;
+  }
+  unsigned long levelfragnum = sectionLevelConvert.levelStarts[levelNum-1]+1;
+
+  if (FragToLevel(levelfragnum, DocNum)) {
+    return true;
+  } 
+  return false;
+  
+
+}
+
+
+
Index: trunk/gsdl/src/mgpp/text/FragLevelConvert.h
===================================================================
--- trunk/gsdl/src/mgpp/text/FragLevelConvert.h	(revision 926)
+++ trunk/gsdl/src/mgpp/text/FragLevelConvert.h	(revision 927)
@@ -29,4 +29,20 @@
 
 
+/*Notes about levelStarts (kjm18) - this is my interpretation of
+whats going on, feel free to correct this if its wrong.
+
+say you have 5 docs, consisting of fragments:
+1:  1-55
+2: 56-83
+3: 84-106
+4: 107-152
+5: 153-211
+
+then levelStarts would have the values
+0  1  2   3   4   5 
+?  55 83 106 152 211
+I dont know whats in position 0.
+
+*/
 class FragLevelConvert {
 protected:
@@ -43,4 +59,13 @@
 
   bool FragToLevel (unsigned long fragNum, unsigned long &levelDocNum) const;
+
+  // this function converts from one level number to another
+  // the FragLevelConvert thats calling the method should be loaded with
+  // the level that you want to convert to, while the sectionLevelConvert
+  // should be loaded with the level converting from.
+  // level Num has the old level, DocNum will be returned with the new
+  // coresponding level
+  bool LevelToLevel (FragLevelConvert sectionLevelConvert,
+		   unsigned long levelNum, unsigned long &DocNum);
 };
 
Index: trunk/gsdl/src/mgpp/text/MGQuery.cpp
===================================================================
--- trunk/gsdl/src/mgpp/text/MGQuery.cpp	(revision 926)
+++ trunk/gsdl/src/mgpp/text/MGQuery.cpp	(revision 927)
@@ -646,2 +646,50 @@
 }
 
+// new MGQuery to retrieve doc and section nums
+// this will return doc nums for the level queried at (set in queryInfo)
+// in QueryResult.docs and if a second level is specified, 
+// it will return corresponding docnums for that level in QueryResult.levels
+void MGQuery (IndexData &indexData,
+	      const QueryInfo &queryInfo,
+	      const QueryNode *queryTree,
+	      ExtQueryResult &realresult, UCArray &level) {
+  realresult.Clear ();
+  QueryResult result; // temp result
+
+  // do the normal query
+  MGQuery (indexData, queryInfo, queryTree, result);
+
+  // now that have the final result stuff, convert to ExtQueryResult,
+  // add in level nums if needed
+
+  realresult.docs = result.docs;
+  realresult.ranks = result.ranks;
+  realresult.termFreqs = result.termFreqs;
+
+  if (queryInfo.docLevel == level || level.empty()) {
+    realresult.levels = result.docs;
+    return;
+  }
+
+  // else need to convert from queryInfo.docLevel to level
+
+  // the original level info
+  FragLevelConvert sectionLevelConverter = indexData.levelConverter;
+
+  // the new level info
+  indexData.LoadLevel(level);
+  
+  unsigned long DocNum = 0;
+  
+  for (unsigned long i=0; i<realresult.docs.size(); i++) {
+
+    // do an if ! here????
+    indexData.levelConverter.LevelToLevel(sectionLevelConverter, realresult.docs[i], DocNum);
+    realresult.levels.push_back(DocNum);
+  }
+  
+}
+
+
+
+
Index: trunk/gsdl/src/mgpp/text/MGQuery.h
===================================================================
--- trunk/gsdl/src/mgpp/text/MGQuery.h	(revision 926)
+++ trunk/gsdl/src/mgpp/text/MGQuery.h	(revision 927)
@@ -114,4 +114,10 @@
 #define NO_TERM_RANGE_END   (LONG_MAX/2)
 
+/* NOTE: range stuff - the range values are for the previous term relative
+to the current term. So if searching for the phrase "the cat", 'the' doesn't 
+need range limits, but 'cat' has a range of -2 to -1. ie, if have found 'cat'
+then 'the' has to be at position between -2 and -1 relative to 'cat'.
+"the cat" could also be searched for by 'cat' with no range limits, then 'the' with range 0 to 1.
+ */
 class TermNode {
 public:
@@ -157,4 +163,11 @@
 	      QueryResult &result);
 
+// this function for retriving results with both section doc nums
+// and Document docnums
+void MGQuery (IndexData &indexData,
+	      const QueryInfo &queryInfo,
+	      const QueryNode *queryTree,
+	      ExtQueryResult &result, UCArray &level);
+
 
 #endif
Index: trunk/gsdl/src/mgpp/text/Terms.cpp
===================================================================
--- trunk/gsdl/src/mgpp/text/Terms.cpp	(revision 926)
+++ trunk/gsdl/src/mgpp/text/Terms.cpp	(revision 927)
@@ -71,4 +71,5 @@
 
 
+
 ostream &operator<< (ostream &s, const QueryResult &r) {
   s << "docs: ";
@@ -96,5 +97,49 @@
 }
 
-
+//---------------------------------------------------
+// new ExtQueryResult stuff
+void ExtQueryResult::Clear () {
+  docs.erase (docs.begin(), docs.end());
+  levels.erase (levels.begin(), levels.end());
+  ranks.erase (ranks.begin(), ranks.end());
+  termFreqs.erase (termFreqs.begin(), termFreqs.end());
+}
+
+ExtQueryResult::ExtQueryResult () {
+  Clear ();
+}
+
+ostream &operator<< (ostream &s, const ExtQueryResult &r) {
+  s << "docs: ";
+  unsigned long i;
+  for (i=0; i<r.docs.size(); i++)
+    s << r.docs[i] << ", ";
+
+  s << "\nlevels: ";
+  for (i=0; i<r.levels.size(); i++)
+    s << r.levels[i] << ", ";
+
+  
+  s << "\nranks: ";
+  for (i=0; i<r.ranks.size(); i++)
+    s << r.ranks[i] << ", ";
+
+  s << "\ntermFreqs: ";
+  for (i=0; i<r.termFreqs.size(); i++)
+    s << r.termFreqs[i] << ", ";
+  s << "\n\n";
+
+  return s;
+}
+
+
+bool operator== (const ExtQueryResult &r1, const ExtQueryResult &r2) {
+  return ((r1.docs == r2.docs) &&
+	  (r1.levels == r2.levels) &&
+	  (r1.ranks == r2.ranks) &&
+	  (r1.termFreqs == r2.termFreqs));
+}
+
+//--------------------------------------
 void FragData::Clear () {
   matchDocs = 0;
Index: trunk/gsdl/src/mgpp/text/Terms.h
===================================================================
--- trunk/gsdl/src/mgpp/text/Terms.h	(revision 926)
+++ trunk/gsdl/src/mgpp/text/Terms.h	(revision 927)
@@ -161,4 +161,21 @@
 			    QueryResult &result);
 
+
+// new QueryResult class to handle retrieval of doc and level nums.
+// Use this class with extended version of MGQuery
+
+class ExtQueryResult : public QueryResult {
+public:
+  DocNumArray levels; // used for returning a different granularity, eg
+  // search sections but return Document numbers, or search Documents, 
+  // return Section numbers.
+ 
+  void Clear ();
+  ExtQueryResult ();
+};
+
+ostream &operator<< (ostream &s, const ExtQueryResult &r);
+bool operator== (const ExtQueryResult &r1, const ExtQueryResult &r2);
+
 #endif
 
Index: trunk/gsdl/src/mgpp/text/mg_perf_hash_build.cpp
===================================================================
--- trunk/gsdl/src/mgpp/text/mg_perf_hash_build.cpp	(revision 926)
+++ trunk/gsdl/src/mgpp/text/mg_perf_hash_build.cpp	(revision 927)
@@ -37,4 +37,9 @@
 /*
    $Log$
+   Revision 1.2  2000/02/15 22:45:22  kjm18
+   added feature to retrieve doc nums at a different level than the level
+   queried at. eg query at Document level, but retrieve section level docnums
+   bug in mg_perf_hash_build.cpp fixed
+
    Revision 1.1  2000/01/14 02:26:19  sjboddie
    Rodgers new C++ mg
@@ -88,6 +93,10 @@
   dictFile = open_file (filename, INVF_DICT_SUFFIX, "rb",
 			MAGIC_STEM_BUILD, MG_ABORT);
+  if (dictFile==NULL) {
+    FatalError(1, "unable to open file");
+  }
   idh.Read (dictFile);
 
+  //cerr << idh.lookback<<" "<<idh.word_dict_start<<endl;
   // go to the start of the word dictionary
   fseek (dictFile, idh.word_dict_start, SEEK_SET);
@@ -99,5 +108,5 @@
   if (!(starts = (u_char **) Xmalloc (sizeof (u_char *) * idh.word_dict_size)))
     FatalError (1, "Out of memory");
-
+  //cerr << "size= "<< idh.word_dict_size<<endl;
   word_dict_el wordEl;
   wordEl.SetNumLevels (idh.num_levels);
@@ -117,9 +126,13 @@
     *pool++ = wordEl.el.size();
     bcopy ((char *) wordEl.el.begin(), (char *) pool, wordEl.el.size());
-    pool += l;
+    //cerr << pool<<"   " <<starts[i]<<endl;
+    pool += wordEl.el.size();
     pool_left -= l;
+    
   }
   fclose (dictFile);
-
+  //cerr << pool<<"   " <<starts[i-1]<<endl;
+  //cerr<<"starts  "<<starts[113529]<<endl;
+  //cerr << starts[17][1] << " "<<starts[25][4]<<endl;
   // create perfect hash file
   hashFile = create_file (filename, INVF_DICT_HASH_SUFFIX, "wb",
