private FacetResult GetDim(string dim, OrdRange ordRange, int topN) { TopOrdAndIntQueue q = null; int bottomCount = 0; int dimCount = 0; int childCount = 0; TopOrdAndIntQueue.OrdAndValue reuse = null; //System.out.println("getDim : " + ordRange.start + " - " + ordRange.end); for (int ord = ordRange.Start; ord <= ordRange.End; ord++) { //System.out.println(" ord=" + ord + " count=" + counts[ord]); if (counts[ord] > 0) { dimCount += counts[ord]; childCount++; if (counts[ord] > bottomCount) { if (reuse == null) { reuse = new TopOrdAndIntQueue.OrdAndValue(); } reuse.Ord = ord; reuse.Value = counts[ord]; if (q == null) { // Lazy init, so we don't create this for the // sparse case unnecessarily q = new TopOrdAndIntQueue(topN); } reuse = q.InsertWithOverflow(reuse); if (q.Size() == topN) { bottomCount = q.Top().Value; } } } } if (q == null) { return(null); } LabelAndValue[] labelValues = new LabelAndValue[q.Size()]; for (int i = labelValues.Length - 1; i >= 0; i--) { TopOrdAndIntQueue.OrdAndValue ordAndValue = q.Pop(); var term = new BytesRef(); dv.LookupOrd(ordAndValue.Ord, term); string[] parts = FacetsConfig.StringToPath(term.Utf8ToString()); labelValues[i] = new LabelAndValue(parts[1], ordAndValue.Value); } return(new FacetResult(dim, new string[0], dimCount, labelValues, childCount)); }
private FacetResult GetDim(string dim, OrdRange ordRange, int topN) { TopOrdAndInt32Queue q = null; int bottomCount = 0; int dimCount = 0; int childCount = 0; //System.out.println("getDim : " + ordRange.start + " - " + ordRange.end); for (int ord = ordRange.Start; ord <= ordRange.End; ord++) { //System.out.println(" ord=" + ord + " count=" + counts[ord]); if (counts[ord] > 0) { dimCount += counts[ord]; childCount++; if (counts[ord] > bottomCount) { if (q == null) { // Lazy init, so we don't create this for the // sparse case unnecessarily q = new TopOrdAndInt32Queue(topN); } // LUCENENET specific - use struct instead of reusing class instance for better performance q.Insert(new OrdAndValue <int>(ord, counts[ord])); if (q.Count == topN) { bottomCount = q.Top.Value; } } } } if (q == null) { return(null); } var scratch = new BytesRef(); LabelAndValue[] labelValues = new LabelAndValue[q.Count]; for (int i = labelValues.Length - 1; i >= 0; i--) { var ordAndValue = q.Pop(); dv.LookupOrd(ordAndValue.Ord, scratch); string[] parts = FacetsConfig.StringToPath(scratch.Utf8ToString()); labelValues[i] = new LabelAndValue(parts[1], ordAndValue.Value); } return(new FacetResult(dim, Arrays.Empty <string>(), dimCount, labelValues, childCount)); }
public static void TestFlexLuceneRAM(string[] args) { StandardAnalyzer analyzer = new StandardAnalyzer(); FlexLucene.Store.Directory index = (FlexLucene.Store.Directory) new RAMDirectory(); config = new IndexWriterConfig((Analyzer)analyzer); cnf = new FacetsConfig(); cnf.SetIndexFieldName("title", "facet_title"); cnf.SetIndexFieldName("isbn", "facet_isbn"); LuceneTest.taxoDir = (FlexLucene.Store.Directory) new RAMDirectory(); LuceneTest.taxoWriter = (TaxonomyWriter) new FlexLucene.Facet.Taxonomy.Directory.DirectoryTaxonomyWriter(LuceneTest.taxoDir, IndexWriterConfigOpenMode.CREATE); IndexWriter w = new IndexWriter(index, LuceneTest.config); addDoc(w, "Lucene in Action", "9900001"); addDoc(w, "Lucene for Dummies", "9900002"); addDoc(w, "Lucene for Dummies 2", "9900003"); w.close(); String querystr = "isbn:99*"; Query q = new QueryParser("title", (Analyzer)analyzer).Parse(querystr); int hitsPerPage = 10; IndexReader reader = (IndexReader)DirectoryReader.Open(index); IndexSearcher searcher = new IndexSearcher(reader); TopScoreDocCollector collector = TopScoreDocCollector.Create(hitsPerPage); searcher.Search(q, (Collector)collector); ScoreDoc[] hits = collector.TopDocs().ScoreDocs; Console.WriteLine("Found " + hits.Length + " hits."); for (int i = 0; i < hits.Length; ++i) { int docId = hits [i].Doc; Document d = searcher.Doc(docId); Console.WriteLine(i + 1 + ". " + d.Get("isbn") + "\t" + d.Get("title")); } SortedSetDocValuesReaderState state = (SortedSetDocValuesReaderState) new DefaultSortedSetDocValuesReaderState(reader, "facet_isbn"); FacetsCollector fc = new FacetsCollector(); FacetsCollector.Search(searcher, q, 10, (Collector)fc); Facets facets = (Facets) new SortedSetDocValuesFacetCounts(state, fc); FacetResult result = facets.GetTopChildren(10, "isbn", new String[0]); for (int j = 0; j < result.ChildCount; ++j) { LabelAndValue lv = result.LabelValues [j]; Console.WriteLine(String.Format("Label={0}, Value={1}", lv.Label, lv.Value)); } reader.close(); }
public override FacetResult GetTopChildren(int topN, string dim, params string[] path) { if (dim.Equals(Field) == false) { throw new System.ArgumentException("invalid dim \"" + dim + "\"; should be \"" + Field + "\""); } if (path.Length != 0) { throw new System.ArgumentException("path.length should be 0"); } LabelAndValue[] labelValues = new LabelAndValue[Counts.Length]; for (int i = 0; i < Counts.Length; i++) { labelValues[i] = new LabelAndValue(Ranges[i].Label, Counts[i]); } return(new FacetResult(dim, path, TotCount, labelValues, labelValues.Length)); }
public override FacetResult GetTopChildren(int topN, string dim, params string[] path) { if (dim.Equals(m_field, StringComparison.Ordinal) == false) { throw new ArgumentException("invalid dim \"" + dim + "\"; should be \"" + m_field + "\""); } if (path.Length != 0) { throw new ArgumentException("path.length should be 0"); } LabelAndValue[] labelValues = new LabelAndValue[m_counts.Length]; for (int i = 0; i < m_counts.Length; i++) { labelValues[i] = new LabelAndValue(m_ranges[i].Label, m_counts[i]); } return(new FacetResult(dim, path, m_totCount, labelValues, labelValues.Length)); }
public override FacetResult GetTopChildren(int topN, string dim, params string[] path) { if (dim.Equals(field) == false) { throw new System.ArgumentException("invalid dim \"" + dim + "\"; should be \"" + field + "\""); } if (path.Length != 0) { throw new System.ArgumentException("path.length should be 0"); } LabelAndValue[] labelValues = new LabelAndValue[counts.Length]; for (int i = 0; i < counts.Length; i++) { labelValues[i] = new LabelAndValue(ranges[i].Label, counts[i]); } return new FacetResult(dim, path, totCount, labelValues, labelValues.Length); }
internal void Load(RedLinkServerCommandLine cmdLine) { List <LabelAndValue> choices = LoadChoices?.Invoke() ?? _Defaults.Select(MakeChoice).ToList(); var currentValue = cmdLine.GetOptionValue(_Mode, _Key); LabelAndValue selection = null; if (currentValue != null) { selection = choices.FirstOrDefault(c => c.Value == currentValue); if (selection == null) { selection = new LabelAndValue(currentValue == "" ? "Unspecified" : currentValue, currentValue); choices.Add(selection); } } Values = choices.ToArray(); Value = selection; }
public override FacetResult GetTopChildren(int topN, string dim, params string[] path) { if (topN <= 0) { throw new System.ArgumentException("topN must be > 0 (got: " + topN + ")"); } var dimConfig = VerifyDim(dim); FacetLabel cp = new FacetLabel(dim, path); int dimOrd = taxoReader.GetOrdinal(cp); if (dimOrd == -1) { return(null); } TopOrdAndIntQueue q = new TopOrdAndIntQueue(Math.Min(taxoReader.Count, topN)); int bottomValue = 0; int ord = children[dimOrd]; int totValue = 0; int childCount = 0; TopOrdAndIntQueue.OrdAndValue reuse = null; while (ord != TaxonomyReader.INVALID_ORDINAL) { if (values[ord] > 0) { totValue += values[ord]; childCount++; if (values[ord] > bottomValue) { if (reuse == null) { reuse = new TopOrdAndIntQueue.OrdAndValue(); } reuse.Ord = ord; reuse.Value = values[ord]; reuse = q.InsertWithOverflow(reuse); if (q.Size() == topN) { bottomValue = q.Top().Value; } } } ord = siblings[ord]; } if (totValue == 0) { return(null); } if (dimConfig.MultiValued) { if (dimConfig.RequireDimCount) { totValue = values[dimOrd]; } else { // Our sum'd value is not correct, in general: totValue = -1; } } else { // Our sum'd dim value is accurate, so we keep it } LabelAndValue[] labelValues = new LabelAndValue[q.Size()]; for (int i = labelValues.Length - 1; i >= 0; i--) { TopOrdAndIntQueue.OrdAndValue ordAndValue = q.Pop(); FacetLabel child = taxoReader.GetPath(ordAndValue.Ord); labelValues[i] = new LabelAndValue(child.Components[cp.Length], ordAndValue.Value); } return(new FacetResult(dim, path, totValue, labelValues, childCount)); }
public override FacetResult GetTopChildren(int topN, string dim, params string[] path) { if (topN <= 0) { throw new ArgumentException("topN must be > 0 (got: " + topN + ")"); } FacetsConfig.DimConfig dimConfig = VerifyDim(dim); FacetLabel cp = new FacetLabel(dim, path); int dimOrd = m_taxoReader.GetOrdinal(cp); if (dimOrd == -1) { return(null); } TopOrdAndSingleQueue q = new TopOrdAndSingleQueue(Math.Min(m_taxoReader.Count, topN)); float bottomValue = 0; int ord = m_children[dimOrd]; float sumValues = 0; int childCount = 0; while (ord != TaxonomyReader.INVALID_ORDINAL) { if (m_values[ord] > 0) { sumValues += m_values[ord]; childCount++; if (m_values[ord] > bottomValue) { // LUCENENET specific - use struct instead of reusing class instance for better performance q.Insert(new OrdAndValue <float>(ord, m_values[ord])); if (q.Count == topN) { bottomValue = q.Top.Value; } } } ord = m_siblings[ord]; } if (sumValues == 0) { return(null); } if (dimConfig.IsMultiValued) { if (dimConfig.RequireDimCount) { sumValues = m_values[dimOrd]; } else { // Our sum'd count is not correct, in general: sumValues = -1; } } else { // Our sum'd dim count is accurate, so we keep it } LabelAndValue[] labelValues = new LabelAndValue[q.Count]; for (int i = labelValues.Length - 1; i >= 0; i--) { var ordAndValue = q.Pop(); FacetLabel child = m_taxoReader.GetPath(ordAndValue.Ord); labelValues[i] = new LabelAndValue(child.Components[cp.Length], ordAndValue.Value); } return(new FacetResult(dim, path, sumValues, labelValues, childCount)); }
public override FacetResult GetTopChildren(int topN, string dim, params string[] path) { if (topN <= 0) { throw new System.ArgumentException("topN must be > 0 (got: " + topN + ")"); } FacetsConfig.DimConfig dimConfig = VerifyDim(dim); FacetLabel cp = new FacetLabel(dim, path); int dimOrd = taxoReader.GetOrdinal(cp); if (dimOrd == -1) { return null; } TopOrdAndFloatQueue q = new TopOrdAndFloatQueue(Math.Min(taxoReader.Count, topN)); float bottomValue = 0; int ord = children[dimOrd]; float sumValues = 0; int childCount = 0; TopOrdAndFloatQueue.OrdAndValue reuse = null; while (ord != TaxonomyReader.INVALID_ORDINAL) { if (values[ord] > 0) { sumValues += values[ord]; childCount++; if (values[ord] > bottomValue) { if (reuse == null) { reuse = new TopOrdAndFloatQueue.OrdAndValue(); } reuse.Ord = ord; reuse.Value = values[ord]; reuse = q.InsertWithOverflow(reuse); if (q.Size() == topN) { bottomValue = q.Top().Value; } } } ord = siblings[ord]; } if (sumValues == 0) { return null; } if (dimConfig.MultiValued) { if (dimConfig.RequireDimCount) { sumValues = values[dimOrd]; } else { // Our sum'd count is not correct, in general: sumValues = -1; } } else { // Our sum'd dim count is accurate, so we keep it } LabelAndValue[] labelValues = new LabelAndValue[q.Size()]; for (int i = labelValues.Length - 1; i >= 0; i--) { TopOrdAndFloatQueue.OrdAndValue ordAndValue = q.Pop(); FacetLabel child = taxoReader.GetPath(ordAndValue.Ord); labelValues[i] = new LabelAndValue(child.Components[cp.Length], ordAndValue.Value); } return new FacetResult(dim, path, sumValues, labelValues, childCount); }
public virtual void TestRandomDoubles() { Directory dir = NewDirectory(); RandomIndexWriter w = new RandomIndexWriter(Random(), dir, Similarity, TimeZone); int numDocs = AtLeast(1000); double[] values = new double[numDocs]; double minValue = double.PositiveInfinity; double maxValue = double.NegativeInfinity; for (int i = 0; i < numDocs; i++) { Document doc = new Document(); double v = Random().NextDouble(); values[i] = v; doc.Add(new DoubleDocValuesField("field", v)); doc.Add(new DoubleField("field", v, Field.Store.NO)); w.AddDocument(doc); minValue = Math.Min(minValue, v); maxValue = Math.Max(maxValue, v); } IndexReader r = w.Reader; IndexSearcher s = NewSearcher(r); FacetsConfig config = new FacetsConfig(); int numIters = AtLeast(10); for (int iter = 0; iter < numIters; iter++) { if (VERBOSE) { Console.WriteLine("TEST: iter=" + iter); } int numRange = TestUtil.NextInt(Random(), 1, 5); DoubleRange[] ranges = new DoubleRange[numRange]; int[] expectedCounts = new int[numRange]; double minAcceptedValue = double.PositiveInfinity; double maxAcceptedValue = double.NegativeInfinity; for (int rangeID = 0; rangeID < numRange; rangeID++) { double min; if (rangeID > 0 && Random().Next(10) == 7) { // Use an existing boundary: DoubleRange prevRange = ranges[Random().Next(rangeID)]; if (Random().NextBoolean()) { min = prevRange.Min; } else { min = prevRange.Max; } } else { min = Random().NextDouble(); } double max; if (rangeID > 0 && Random().Next(10) == 7) { // Use an existing boundary: DoubleRange prevRange = ranges[Random().Next(rangeID)]; if (Random().NextBoolean()) { max = prevRange.Min; } else { max = prevRange.Max; } } else { max = Random().NextDouble(); } if (min > max) { double x = min; min = max; max = x; } bool minIncl; bool maxIncl; if (min == max) { minIncl = true; maxIncl = true; } else { minIncl = Random().NextBoolean(); maxIncl = Random().NextBoolean(); } ranges[rangeID] = new DoubleRange("r" + rangeID, min, minIncl, max, maxIncl); // Do "slow but hopefully correct" computation of // expected count: for (int i = 0; i < numDocs; i++) { bool accept = true; if (minIncl) { accept &= values[i] >= min; } else { accept &= values[i] > min; } if (maxIncl) { accept &= values[i] <= max; } else { accept &= values[i] < max; } if (accept) { expectedCounts[rangeID]++; minAcceptedValue = Math.Min(minAcceptedValue, values[i]); maxAcceptedValue = Math.Max(maxAcceptedValue, values[i]); } } } FacetsCollector sfc = new FacetsCollector(); s.Search(new MatchAllDocsQuery(), sfc); Filter fastMatchFilter; if (Random().NextBoolean()) { if (Random().NextBoolean()) { fastMatchFilter = NumericRangeFilter.NewDoubleRange("field", minValue, maxValue, true, true); } else { fastMatchFilter = NumericRangeFilter.NewDoubleRange("field", minAcceptedValue, maxAcceptedValue, true, true); } } else { fastMatchFilter = null; } ValueSource vs = new DoubleFieldSource("field"); Facets facets = new DoubleRangeFacetCounts("field", vs, sfc, fastMatchFilter, ranges); FacetResult result = facets.GetTopChildren(10, "field"); Assert.AreEqual(numRange, result.LabelValues.Length); for (int rangeID = 0; rangeID < numRange; rangeID++) { if (VERBOSE) { Console.WriteLine(" range " + rangeID + " expectedCount=" + expectedCounts[rangeID]); } LabelAndValue subNode = result.LabelValues[rangeID]; Assert.AreEqual("r" + rangeID, subNode.Label); Assert.AreEqual(expectedCounts[rangeID], (int)subNode.Value); DoubleRange range = ranges[rangeID]; // Test drill-down: DrillDownQuery ddq = new DrillDownQuery(config); if (Random().NextBoolean()) { if (Random().NextBoolean()) { ddq.Add("field", NumericRangeFilter.NewDoubleRange("field", range.Min, range.Max, range.MinInclusive, range.MaxInclusive)); } else { ddq.Add("field", NumericRangeQuery.NewDoubleRange("field", range.Min, range.Max, range.MinInclusive, range.MaxInclusive)); } } else { ddq.Add("field", range.GetFilter(fastMatchFilter, vs)); } Assert.AreEqual(expectedCounts[rangeID], s.Search(ddq, 10).TotalHits); } } IOUtils.Close(w, r, dir); }
public virtual void TestRandomFloats() { Directory dir = NewDirectory(); RandomIndexWriter w = new RandomIndexWriter( #if FEATURE_INSTANCE_TESTDATA_INITIALIZATION this, #endif Random, dir); int numDocs = AtLeast(1000); float[] values = new float[numDocs]; float minValue = float.PositiveInfinity; float maxValue = float.NegativeInfinity; for (int i = 0; i < numDocs; i++) { Document doc = new Document(); float v = Random.NextSingle(); values[i] = v; doc.Add(new SingleDocValuesField("field", v)); doc.Add(new SingleField("field", v, Field.Store.NO)); w.AddDocument(doc); minValue = Math.Min(minValue, v); maxValue = Math.Max(maxValue, v); } IndexReader r = w.GetReader(); IndexSearcher s = NewSearcher(r); FacetsConfig config = new FacetsConfig(); int numIters = AtLeast(10); for (int iter = 0; iter < numIters; iter++) { if (VERBOSE) { Console.WriteLine("TEST: iter=" + iter); } int numRange = TestUtil.NextInt32(Random, 1, 5); DoubleRange[] ranges = new DoubleRange[numRange]; int[] expectedCounts = new int[numRange]; float minAcceptedValue = float.PositiveInfinity; float maxAcceptedValue = float.NegativeInfinity; if (VERBOSE) { Console.WriteLine("TEST: " + numRange + " ranges"); } for (int rangeID = 0; rangeID < numRange; rangeID++) { double min; if (rangeID > 0 && Random.Next(10) == 7) { // Use an existing boundary: DoubleRange prevRange = ranges[Random.Next(rangeID)]; if (Random.NextBoolean()) { min = prevRange.Min; } else { min = prevRange.Max; } } else { min = Random.NextDouble(); } double max; if (rangeID > 0 && Random.Next(10) == 7) { // Use an existing boundary: DoubleRange prevRange = ranges[Random.Next(rangeID)]; if (Random.NextBoolean()) { max = prevRange.Min; } else { max = prevRange.Max; } } else { max = Random.NextDouble(); } if (min > max) { double x = min; min = max; max = x; } // Must truncate to float precision so that the // drill-down counts (which use NRQ.newFloatRange) // are correct: min = (float)min; max = (float)max; bool minIncl; bool maxIncl; if (min == max) { minIncl = true; maxIncl = true; } else { minIncl = Random.NextBoolean(); maxIncl = Random.NextBoolean(); } ranges[rangeID] = new DoubleRange("r" + rangeID, min, minIncl, max, maxIncl); if (VERBOSE) { Console.WriteLine("TEST: range " + rangeID + ": " + ranges[rangeID]); } // Do "slow but hopefully correct" computation of // expected count: for (int i = 0; i < numDocs; i++) { bool accept = true; if (minIncl) { accept &= values[i] >= min; } else { accept &= values[i] > min; } if (maxIncl) { accept &= values[i] <= max; } else { accept &= values[i] < max; } if (VERBOSE) { Console.WriteLine("TEST: check doc=" + i + " val=" + values[i] + " accept=" + accept); } if (accept) { expectedCounts[rangeID]++; minAcceptedValue = Math.Min(minAcceptedValue, values[i]); maxAcceptedValue = Math.Max(maxAcceptedValue, values[i]); } } } FacetsCollector sfc = new FacetsCollector(); s.Search(new MatchAllDocsQuery(), sfc); Filter fastMatchFilter; if (Random.NextBoolean()) { if (Random.NextBoolean()) { fastMatchFilter = NumericRangeFilter.NewSingleRange("field", minValue, maxValue, true, true); } else { fastMatchFilter = NumericRangeFilter.NewSingleRange("field", minAcceptedValue, maxAcceptedValue, true, true); } } else { fastMatchFilter = null; } ValueSource vs = new SingleFieldSource("field"); Facets facets = new DoubleRangeFacetCounts("field", vs, sfc, fastMatchFilter, ranges); FacetResult result = facets.GetTopChildren(10, "field"); Assert.AreEqual(numRange, result.LabelValues.Length); for (int rangeID = 0; rangeID < numRange; rangeID++) { if (VERBOSE) { Console.WriteLine("TEST: verify range " + rangeID + " expectedCount=" + expectedCounts[rangeID]); } LabelAndValue subNode = result.LabelValues[rangeID]; Assert.AreEqual("r" + rangeID, subNode.Label); Assert.AreEqual(expectedCounts[rangeID], (int)subNode.Value); DoubleRange range = ranges[rangeID]; // Test drill-down: DrillDownQuery ddq = new DrillDownQuery(config); if (Random.NextBoolean()) { if (Random.NextBoolean()) { ddq.Add("field", NumericRangeFilter.NewSingleRange("field", (float)range.Min, (float)range.Max, range.MinInclusive, range.MaxInclusive)); } else { ddq.Add("field", NumericRangeQuery.NewSingleRange("field", (float)range.Min, (float)range.Max, range.MinInclusive, range.MaxInclusive)); } } else { ddq.Add("field", range.GetFilter(fastMatchFilter, vs)); } Assert.AreEqual(expectedCounts[rangeID], s.Search(ddq, 10).TotalHits); } } IOUtils.Dispose(w, r, dir); }
} // ListPropertiesPerDefaultToString method (3 of 4) /// <summary> /// Format names and values of the properties reported by the ToString /// method on any object for rendering on a report, such as the console /// display of a character-mode application. /// </summary> /// <param name="pobjToList"> /// Pass in a reference to the object of interest. Its ToString method, /// presumably a custom (overrridden) method is called, and the string /// that it returns is parsed and formatted. /// /// Its ToString method is expected to return a string that begins with /// the object's internal name (type), followed by a colon and a list of /// properties. Each property is expected to be listed as a name-value /// pair, with the name and its value sapearated by an equals sign, and /// properties delimited by either a single character, such as a comma, /// or the platform-dependent newline sequence, e. g., CR/LF for Windows /// or LF for Linux. /// </param> /// <param name="pchrDelimiter"> /// Pass in the single-character delimiter that separates property names /// and their values from each other. To specify that the pairs are /// delimited by newlines, specify SpecialCharacters.NULL_CHAR, the NULL /// (numeric value zero) character. /// </param> /// <param name="pintAdditionalPaddingChars"> /// Specify the number of characters of extra white space, if any, to be /// prepended to subsequent output lines to cause the report to aligne /// vertically. This is useful when the format string through which it /// will be written contains text that precedes the output string, which /// would otherwise cause subsequent detail lines to be misaligned. /// </param> /// <returns> /// The return value is a string that can be fed through a standard /// format item to string.Format, Console.WriteLine, or any of their /// cousins. /// </returns> public static string ListPropertiesPerDefaultToString ( object pobjToList , char pchrDelimiter , int pintAdditionalPaddingChars ) { const string THIRD_FORMAT_ITEM = @" {2}{3}"; StringBuilder rsb = null; string [ ] astrProperties = null; astrProperties = pchrDelimiter == SpecialCharacters.NULL_CHAR ? WizardWrx.EmbeddedTextFile.Readers.StringOfLinesToArray ( pobjToList.ToString ( ) ) : pobjToList.ToString ( ).Split ( pchrDelimiter ); LabelAndValue [ ] autpLabelAndValue = new LabelAndValue [ astrProperties.Length ]; string strTypeName = null; // The string.IsNullOrEmpty method requires an initialized argument. for ( int intIndex = ArrayInfo.ARRAY_FIRST_ELEMENT ; intIndex < astrProperties.Length ; intIndex++ ) { string [ ] astrLabelAndItsValue = null; if ( intIndex == ArrayInfo.ARRAY_FIRST_ELEMENT ) { // The first item contains also the property type name, followed by a colon and a space. int intPosColon = astrProperties [ intIndex ].IndexOf ( SpecialCharacters.COLON ); int intPosNext = intPosColon + ArrayInfo.NEXT_INDEX; // ------------------------------------------------ // As always, use a belt and suspenders, covering // the chance that the first label immediately // follows the colon that delimits it from the // object type name. // // Whether the break occurs at the colon or the // immediately following space, the position is set // such that the last charecter goes into the type // name field, leaving the remainder of the string // to be divided into the propertry value and its // label. // ------------------------------------------------ int intPosBreak = ArrayInfo.OrdinalFromIndex ( astrProperties [ intIndex ] [ intPosNext ] == SpecialCharacters.SPACE_CHAR ? intPosNext : intPosColon ); strTypeName = astrProperties [ intIndex ].Substring ( ListInfo.SUBSTR_BEGINNING , intPosBreak ); astrLabelAndItsValue = astrProperties [ intIndex ].Substring ( intPosBreak ).Split ( SpecialCharacters.EQUALS_SIGN ); } // TRUE (This iteration processess the first property item.) block, if ( intIndex == ArrayInfo.ARRAY_FIRST_ELEMENT ) else { astrLabelAndItsValue = astrProperties [ intIndex ].Split ( SpecialCharacters.EQUALS_SIGN ); } // FALSE (This iteration processes a subsequent property item.) block, if ( intIndex == ArrayInfo.ARRAY_FIRST_ELEMENT ) autpLabelAndValue [ intIndex ].Label = astrLabelAndItsValue [ ArrayInfo.ARRAY_FIRST_ELEMENT ].Trim ( ); autpLabelAndValue [ intIndex ].Value = astrLabelAndItsValue [ ArrayInfo.ARRAY_SECOND_ELEMENT ].Trim ( ); } // for ( int intIndex = ArrayInfo.ARRAY_FIRST_ELEMENT ; intIndex < astrProperties.Length ; intIndex++ ) // -------------------------------------------------------- // Compute the length of the longest label string, so that // a format string that renders the labels and their values // in a neatly aligned list can be constructed. // -------------------------------------------------------- int intLabelFieldWidth = ComputeLabelFieldWidth ( autpLabelAndValue ); string strPropertyPadding = SpecialStrings.EMPTY_STRING.PadRight ( strTypeName.Length ); // -------------------------------------------------------- // A string is constructed with two right-padded format // items and a third and fourth default format items. // // 1) The first format item gets the type name string, // strTypeName, on the first iteration of a loop over // the autpLabelAndValue array, while subsequent // iterations use the strPropertyPadding string. // // 2) The second format item gets the property name from // the Label member of a LabelAndValue structure stored // in the current element of the autpLabelAndValue // array. // // 3) The third format item gets the Value member of the // LabelAndValue structure stored in the current // element of the autpLabelAndValue array. // // 4) The fourth format item gets the platform-specific // newline character or sequence thereof. // -------------------------------------------------------- string strDynamicFormatString = string.Concat ( new string [ ] { FormatItem.AdjustToMaximumWidth ( ArrayInfo.ARRAY_FIRST_ELEMENT , strTypeName.Length , FormatItem.Alignment.Left , SpecialStrings.EMPTY_STRING ) , SpecialCharacters.SPACE_CHAR.ToString ( ) , FormatItem.AdjustToMaximumWidth ( ArrayInfo.ARRAY_SECOND_ELEMENT , intLabelFieldWidth , FormatItem.Alignment.Left , SpecialStrings.EMPTY_STRING ) , THIRD_FORMAT_ITEM } ); // -------------------------------------------------------- // The initial capacity of the StringBuilder is twice the // label width plus the length of the type name, times the // number of label/value pairs in the autpLabelAndValue // array. // -------------------------------------------------------- rsb = new StringBuilder ( ( intLabelFieldWidth * MagicNumbers.PLUS_TWO + strTypeName.Length ) * autpLabelAndValue.Length ); for ( int intItemIndex = ArrayInfo.ARRAY_FIRST_ELEMENT ; intItemIndex < autpLabelAndValue.Length ; intItemIndex++ ) { rsb.AppendFormat ( strDynamicFormatString , new string [ ] { intItemIndex == ArrayInfo.ARRAY_FIRST_ELEMENT ? strTypeName : strPropertyPadding , autpLabelAndValue [ intItemIndex ].Label , autpLabelAndValue [ intItemIndex ].Value , Environment.NewLine } ); // ------------------------------------------------------------ // Unless pintAdditionalPaddingChars is zero, the first pass // generates a new format control string that allows more // characters to its first format item. // ------------------------------------------------------------ if ( pintAdditionalPaddingChars > ListInfo.EMPTY_STRING_LENGTH && intItemIndex == ArrayInfo.ARRAY_FIRST_ELEMENT ) { strDynamicFormatString = string.Concat ( new string [ ] { FormatItem.AdjustToMaximumWidth ( ArrayInfo.ARRAY_FIRST_ELEMENT , strTypeName.Length + pintAdditionalPaddingChars , FormatItem.Alignment.Left , SpecialStrings.EMPTY_STRING ) , SpecialCharacters.SPACE_CHAR.ToString ( ) , FormatItem.AdjustToMaximumWidth ( ArrayInfo.ARRAY_SECOND_ELEMENT , intLabelFieldWidth , FormatItem.Alignment.Left , SpecialStrings.EMPTY_STRING ) , THIRD_FORMAT_ITEM } ); } // if ( pintAdditionalPaddingChars > ListInfo.EMPTY_STRING_LENGTH && intItemIndex == ArrayInfo.ARRAY_FIRST_ELEMENT ) } // for ( int intItemIndex = ArrayInfo.ARRAY_FIRST_ELEMENT ; intItemIndex < autpLabelAndValue.Length ; intItemIndex++ ) return rsb.ToString ( ); } // ListPropertiesPerDefaultToString method (4 of 4)
public virtual void TestRandomLongs() { Directory dir = NewDirectory(); var w = new RandomIndexWriter( #if FEATURE_INSTANCE_TESTDATA_INITIALIZATION this, #endif Random, dir); int numDocs = AtLeast(1000); if (Verbose) { Console.WriteLine("TEST: numDocs=" + numDocs); } long[] values = new long[numDocs]; long minValue = long.MaxValue; long maxValue = long.MinValue; for (int i = 0; i < numDocs; i++) { Document doc = new Document(); long v = Random.NextInt64(); values[i] = v; doc.Add(new NumericDocValuesField("field", v)); doc.Add(new Int64Field("field", v, Field.Store.NO)); w.AddDocument(doc); minValue = Math.Min(minValue, v); maxValue = Math.Max(maxValue, v); } IndexReader r = w.GetReader(); IndexSearcher s = NewSearcher(r); FacetsConfig config = new FacetsConfig(); int numIters = AtLeast(10); for (int iter = 0; iter < numIters; iter++) { if (Verbose) { Console.WriteLine("TEST: iter=" + iter); } int numRange = TestUtil.NextInt32(Random, 1, 100); Int64Range[] ranges = new Int64Range[numRange]; int[] expectedCounts = new int[numRange]; long minAcceptedValue = long.MaxValue; long maxAcceptedValue = long.MinValue; for (int rangeID = 0; rangeID < numRange; rangeID++) { long min; if (rangeID > 0 && Random.Next(10) == 7) { // Use an existing boundary: Int64Range prevRange = ranges[Random.Next(rangeID)]; if (Random.NextBoolean()) { min = prevRange.Min; } else { min = prevRange.Max; } } else { min = Random.NextInt64(); } long max; if (rangeID > 0 && Random.Next(10) == 7) { // Use an existing boundary: Int64Range prevRange = ranges[Random.Next(rangeID)]; if (Random.NextBoolean()) { max = prevRange.Min; } else { max = prevRange.Max; } } else { max = Random.NextInt64(); } if (min > max) { long x = min; min = max; max = x; } bool minIncl; bool maxIncl; if (min == max) { minIncl = true; maxIncl = true; } else { minIncl = Random.NextBoolean(); maxIncl = Random.NextBoolean(); } ranges[rangeID] = new Int64Range("r" + rangeID, min, minIncl, max, maxIncl); if (Verbose) { Console.WriteLine(" range " + rangeID + ": " + ranges[rangeID]); } // Do "slow but hopefully correct" computation of // expected count: for (int i = 0; i < numDocs; i++) { bool accept = true; if (minIncl) { accept &= values[i] >= min; } else { accept &= values[i] > min; } if (maxIncl) { accept &= values[i] <= max; } else { accept &= values[i] < max; } if (accept) { expectedCounts[rangeID]++; minAcceptedValue = Math.Min(minAcceptedValue, values[i]); maxAcceptedValue = Math.Max(maxAcceptedValue, values[i]); } } } FacetsCollector sfc = new FacetsCollector(); s.Search(new MatchAllDocsQuery(), sfc); Filter fastMatchFilter; if (Random.NextBoolean()) { if (Random.NextBoolean()) { fastMatchFilter = NumericRangeFilter.NewInt64Range("field", minValue, maxValue, true, true); } else { fastMatchFilter = NumericRangeFilter.NewInt64Range("field", minAcceptedValue, maxAcceptedValue, true, true); } } else { fastMatchFilter = null; } ValueSource vs = new Int64FieldSource("field"); Facets facets = new Int64RangeFacetCounts("field", vs, sfc, fastMatchFilter, ranges); FacetResult result = facets.GetTopChildren(10, "field"); Assert.AreEqual(numRange, result.LabelValues.Length); for (int rangeID = 0; rangeID < numRange; rangeID++) { if (Verbose) { Console.WriteLine(" range " + rangeID + " expectedCount=" + expectedCounts[rangeID]); } LabelAndValue subNode = result.LabelValues[rangeID]; Assert.AreEqual("r" + rangeID, subNode.Label); Assert.AreEqual(expectedCounts[rangeID], (int)subNode.Value); Int64Range range = ranges[rangeID]; // Test drill-down: DrillDownQuery ddq = new DrillDownQuery(config); if (Random.NextBoolean()) { if (Random.NextBoolean()) { ddq.Add("field", NumericRangeFilter.NewInt64Range("field", range.Min, range.Max, range.MinInclusive, range.MaxInclusive)); } else { ddq.Add("field", NumericRangeQuery.NewInt64Range("field", range.Min, range.Max, range.MinInclusive, range.MaxInclusive)); } } else { ddq.Add("field", range.GetFilter(fastMatchFilter, vs)); } Assert.AreEqual(expectedCounts[rangeID], s.Search(ddq, 10).TotalHits); } } IOUtils.Dispose(w, r, dir); }