lucenenet-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From paulir...@apache.org
Subject [27/53] [abbrv] git commit: Port Facet.Util and dependencies
Date Thu, 07 Nov 2013 13:53:42 GMT
Port Facet.Util and dependencies


Project: http://git-wip-us.apache.org/repos/asf/lucenenet/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucenenet/commit/9184d142
Tree: http://git-wip-us.apache.org/repos/asf/lucenenet/tree/9184d142
Diff: http://git-wip-us.apache.org/repos/asf/lucenenet/diff/9184d142

Branch: refs/heads/branch_4x
Commit: 9184d142302e908cdf2c2d772f5dfd88ac620890
Parents: db375f9
Author: Paul Irwin <paulirwin@gmail.com>
Authored: Sun Nov 3 18:25:24 2013 -0500
Committer: Paul Irwin <paulirwin@gmail.com>
Committed: Sun Nov 3 18:25:24 2013 -0500

----------------------------------------------------------------------
 src/contrib/Facet/Contrib.Facet.csproj          |  24 +
 .../Facet/Encoding/DGapVInt8IntDecoder.cs       |  45 ++
 .../Facet/Encoding/DGapVInt8IntEncoder.cs       |  75 +++
 src/contrib/Facet/Encoding/IntDecoder.cs        |  13 +
 src/contrib/Facet/Encoding/IntEncoder.cs        |  19 +
 src/contrib/Facet/Encoding/IntEncoderFilter.cs  |  17 +
 src/contrib/Facet/Encoding/SortingIntEncoder.cs |  33 +
 .../Facet/Encoding/UniqueValuesIntEncoder.cs    |  44 ++
 src/contrib/Facet/Params/CategoryListParams.cs  |  84 +++
 src/contrib/Facet/Params/FacetIndexingParams.cs | 115 ++++
 .../Search/DocValuesCategoryListIterator.cs     |  68 ++
 src/contrib/Facet/Search/FacetResultNode.cs     |  49 ++
 .../Facet/Search/ICategoryListIterator.cs       |  16 +
 src/contrib/Facet/Search/IHeap.cs               |  17 +
 src/contrib/Facet/Search/IScoredDocIDs.cs       |  17 +
 .../Facet/Search/IScoredDocIDsIterator.cs       |  26 +
 .../Facet/Util/FacetsPayloadMigrationReader.cs  | 206 ++++++
 .../Facet/Util/MultiCategoryListIterator.cs     |  51 ++
 .../Facet/Util/OrdinalMappingAtomicReader.cs    |  86 +++
 src/contrib/Facet/Util/PartitionsUtils.cs       |  40 ++
 src/contrib/Facet/Util/PrintTaxonomyStats.cs    |  89 +++
 src/contrib/Facet/Util/ResultSortUtils.cs       | 160 +++++
 src/contrib/Facet/Util/ScoredDocIdsUtils.cs     | 642 +++++++++++++++++++
 src/contrib/Facet/Util/TaxonomyMergeUtils.cs    |  40 ++
 24 files changed, 1976 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucenenet/blob/9184d142/src/contrib/Facet/Contrib.Facet.csproj
----------------------------------------------------------------------
diff --git a/src/contrib/Facet/Contrib.Facet.csproj b/src/contrib/Facet/Contrib.Facet.csproj
index b0c0181..f6dc66e 100644
--- a/src/contrib/Facet/Contrib.Facet.csproj
+++ b/src/contrib/Facet/Contrib.Facet.csproj
@@ -40,10 +40,25 @@
   </ItemGroup>
   <ItemGroup>
     <Compile Include="Collections\LRUHashMap.cs" />
+    <Compile Include="Encoding\DGapVInt8IntDecoder.cs" />
+    <Compile Include="Encoding\DGapVInt8IntEncoder.cs" />
+    <Compile Include="Encoding\IntDecoder.cs" />
+    <Compile Include="Encoding\IntEncoder.cs" />
+    <Compile Include="Encoding\IntEncoderFilter.cs" />
+    <Compile Include="Encoding\SortingIntEncoder.cs" />
+    <Compile Include="Encoding\UniqueValuesIntEncoder.cs" />
+    <Compile Include="Params\CategoryListParams.cs" />
+    <Compile Include="Params\FacetIndexingParams.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="Search\DocValuesCategoryListIterator.cs" />
     <Compile Include="Search\FacetArrays.cs" />
     <Compile Include="Search\FacetRequest.cs" />
+    <Compile Include="Search\FacetResultNode.cs" />
     <Compile Include="Search\IAggregator.cs" />
+    <Compile Include="Search\ICategoryListIterator.cs" />
+    <Compile Include="Search\IHeap.cs" />
+    <Compile Include="Search\IScoredDocIDs.cs" />
+    <Compile Include="Search\IScoredDocIDsIterator.cs" />
     <Compile Include="Taxonomy\CategoryPath.cs" />
     <Compile Include="Taxonomy\Directory\Consts.cs" />
     <Compile Include="Taxonomy\Directory\DirectoryTaxonomyReader.cs" />
@@ -62,6 +77,14 @@
     <Compile Include="Taxonomy\WriterCache\Lru\LruTaxonomyWriterCache.cs" />
     <Compile Include="Taxonomy\WriterCache\Lru\NameHashIntCacheLRU.cs" />
     <Compile Include="Taxonomy\WriterCache\Lru\NameIntCacheLRU.cs" />
+    <Compile Include="Util\FacetsPayloadMigrationReader.cs" />
+    <Compile Include="Util\MultiCategoryListIterator.cs" />
+    <Compile Include="Util\OrdinalMappingAtomicReader.cs" />
+    <Compile Include="Util\PartitionsUtils.cs" />
+    <Compile Include="Util\PrintTaxonomyStats.cs" />
+    <Compile Include="Util\ResultSortUtils.cs" />
+    <Compile Include="Util\ScoredDocIdsUtils.cs" />
+    <Compile Include="Util\TaxonomyMergeUtils.cs" />
   </ItemGroup>
   <ItemGroup>
     <ProjectReference Include="..\..\core\Lucene.Net.csproj">
@@ -69,6 +92,7 @@
       <Name>Lucene.Net</Name>
     </ProjectReference>
   </ItemGroup>
+  <ItemGroup />
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
        Other similar extension points exist, see Microsoft.Common.targets.

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/9184d142/src/contrib/Facet/Encoding/DGapVInt8IntDecoder.cs
----------------------------------------------------------------------
diff --git a/src/contrib/Facet/Encoding/DGapVInt8IntDecoder.cs b/src/contrib/Facet/Encoding/DGapVInt8IntDecoder.cs
new file mode 100644
index 0000000..efc171f
--- /dev/null
+++ b/src/contrib/Facet/Encoding/DGapVInt8IntDecoder.cs
@@ -0,0 +1,45 @@
+using Lucene.Net.Util;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Lucene.Net.Facet.Encoding
+{
+    public sealed class DGapVInt8IntDecoder : IntDecoder
+    {
+        public override void Decode(BytesRef buf, IntsRef values)
+        {
+            values.offset = values.length = 0;
+            if (values.ints.Length < buf.length)
+            {
+                values.ints = new int[ArrayUtil.Oversize(buf.length, RamUsageEstimator.NUM_BYTES_INT)];
+            }
+
+            int upto = buf.offset + buf.length;
+            int value = 0;
+            int offset = buf.offset;
+            int prev = 0;
+            while (offset < upto)
+            {
+                sbyte b = buf.bytes[offset++];
+                if (b >= 0)
+                {
+                    values.ints[values.length] = ((value << 7) | (byte)b) + prev;
+                    value = 0;
+                    prev = values.ints[values.length];
+                    values.length++;
+                }
+                else
+                {
+                    value = (value << 7) | (b & 0x7F);
+                }
+            }
+        }
+
+        public override string ToString()
+        {
+            return @"DGapVInt8";
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/9184d142/src/contrib/Facet/Encoding/DGapVInt8IntEncoder.cs
----------------------------------------------------------------------
diff --git a/src/contrib/Facet/Encoding/DGapVInt8IntEncoder.cs b/src/contrib/Facet/Encoding/DGapVInt8IntEncoder.cs
new file mode 100644
index 0000000..82c634e
--- /dev/null
+++ b/src/contrib/Facet/Encoding/DGapVInt8IntEncoder.cs
@@ -0,0 +1,75 @@
+using Lucene.Net.Util;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Lucene.Net.Facet.Encoding
+{
+    public sealed class DGapVInt8IntEncoder : IntEncoder
+    {
+        public override void Encode(IntsRef values, BytesRef buf)
+        {
+            buf.offset = buf.length = 0;
+            int maxBytesNeeded = 5 * values.length;
+            if (buf.bytes.Length < maxBytesNeeded)
+            {
+                buf.Grow(maxBytesNeeded);
+            }
+
+            int upto = values.offset + values.length;
+            int prev = 0;
+            for (int i = values.offset; i < upto; i++)
+            {
+                int value = values.ints[i] - prev;
+                if ((value & ~0x7F) == 0)
+                {
+                    buf.bytes[buf.length] = (sbyte)value;
+                    buf.length++;
+                }
+                else if ((value & ~0x3FFF) == 0)
+                {
+                    buf.bytes[buf.length] = (sbyte)(0x80 | ((value & 0x3F80) >> 7));
+                    buf.bytes[buf.length + 1] = (sbyte)(value & 0x7F);
+                    buf.length += 2;
+                }
+                else if ((value & ~0x1FFFFF) == 0)
+                {
+                    buf.bytes[buf.length] = (sbyte)(0x80 | ((value & 0x1FC000) >> 14));
+                    buf.bytes[buf.length + 1] = (sbyte)(0x80 | ((value & 0x3F80) >> 7));
+                    buf.bytes[buf.length + 2] = (sbyte)(value & 0x7F);
+                    buf.length += 3;
+                }
+                else if ((value & ~0xFFFFFFF) == 0)
+                {
+                    buf.bytes[buf.length] = (sbyte)(0x80 | ((value & 0xFE00000) >> 21));
+                    buf.bytes[buf.length + 1] = (sbyte)(0x80 | ((value & 0x1FC000) >> 14));
+                    buf.bytes[buf.length + 2] = (sbyte)(0x80 | ((value & 0x3F80) >> 7));
+                    buf.bytes[buf.length + 3] = (sbyte)(value & 0x7F);
+                    buf.length += 4;
+                }
+                else
+                {
+                    buf.bytes[buf.length] = (sbyte)(0x80 | ((value & 0xF0000000) >> 28));
+                    buf.bytes[buf.length + 1] = (sbyte)(0x80 | ((value & 0xFE00000) >> 21));
+                    buf.bytes[buf.length + 2] = (sbyte)(0x80 | ((value & 0x1FC000) >> 14));
+                    buf.bytes[buf.length + 3] = (sbyte)(0x80 | ((value & 0x3F80) >> 7));
+                    buf.bytes[buf.length + 4] = (sbyte)(value & 0x7F);
+                    buf.length += 5;
+                }
+
+                prev = values.ints[i];
+            }
+        }
+
+        public override IntDecoder CreateMatchingDecoder()
+        {
+            return new DGapVInt8IntDecoder();
+        }
+
+        public override string ToString()
+        {
+            return @"DGapVInt8";
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/9184d142/src/contrib/Facet/Encoding/IntDecoder.cs
----------------------------------------------------------------------
diff --git a/src/contrib/Facet/Encoding/IntDecoder.cs b/src/contrib/Facet/Encoding/IntDecoder.cs
new file mode 100644
index 0000000..e1810a7
--- /dev/null
+++ b/src/contrib/Facet/Encoding/IntDecoder.cs
@@ -0,0 +1,13 @@
+using Lucene.Net.Util;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Lucene.Net.Facet.Encoding
+{
+    public abstract class IntDecoder
+    {
+        public abstract void Decode(BytesRef buf, IntsRef values);
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/9184d142/src/contrib/Facet/Encoding/IntEncoder.cs
----------------------------------------------------------------------
diff --git a/src/contrib/Facet/Encoding/IntEncoder.cs b/src/contrib/Facet/Encoding/IntEncoder.cs
new file mode 100644
index 0000000..486e6a7
--- /dev/null
+++ b/src/contrib/Facet/Encoding/IntEncoder.cs
@@ -0,0 +1,19 @@
+using Lucene.Net.Util;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Lucene.Net.Facet.Encoding
+{
+    public abstract class IntEncoder
+    {
+        public IntEncoder()
+        {
+        }
+
+        public abstract void Encode(IntsRef values, BytesRef buf);
+
+        public abstract IntDecoder CreateMatchingDecoder();
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/9184d142/src/contrib/Facet/Encoding/IntEncoderFilter.cs
----------------------------------------------------------------------
diff --git a/src/contrib/Facet/Encoding/IntEncoderFilter.cs b/src/contrib/Facet/Encoding/IntEncoderFilter.cs
new file mode 100644
index 0000000..ee97590
--- /dev/null
+++ b/src/contrib/Facet/Encoding/IntEncoderFilter.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Lucene.Net.Facet.Encoding
+{
+    public abstract class IntEncoderFilter : IntEncoder
+    {
+        protected readonly IntEncoder encoder;
+
+        protected IntEncoderFilter(IntEncoder encoder)
+        {
+            this.encoder = encoder;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/9184d142/src/contrib/Facet/Encoding/SortingIntEncoder.cs
----------------------------------------------------------------------
diff --git a/src/contrib/Facet/Encoding/SortingIntEncoder.cs b/src/contrib/Facet/Encoding/SortingIntEncoder.cs
new file mode 100644
index 0000000..08a16f4
--- /dev/null
+++ b/src/contrib/Facet/Encoding/SortingIntEncoder.cs
@@ -0,0 +1,33 @@
+using Lucene.Net.Support;
+using Lucene.Net.Util;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Lucene.Net.Facet.Encoding
+{
+    public sealed class SortingIntEncoder : IntEncoderFilter
+    {
+        public SortingIntEncoder(IntEncoder encoder)
+            : base(encoder)
+        {
+        }
+
+        public override void Encode(IntsRef values, BytesRef buf)
+        {
+            Array.Sort(values.ints, values.offset, values.offset + values.length);
+            encoder.Encode(values, buf);
+        }
+
+        public override IntDecoder CreateMatchingDecoder()
+        {
+            return encoder.CreateMatchingDecoder();
+        }
+
+        public override string ToString()
+        {
+            return @"Sorting(" + encoder.ToString() + @")";
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/9184d142/src/contrib/Facet/Encoding/UniqueValuesIntEncoder.cs
----------------------------------------------------------------------
diff --git a/src/contrib/Facet/Encoding/UniqueValuesIntEncoder.cs b/src/contrib/Facet/Encoding/UniqueValuesIntEncoder.cs
new file mode 100644
index 0000000..2a7b1c5
--- /dev/null
+++ b/src/contrib/Facet/Encoding/UniqueValuesIntEncoder.cs
@@ -0,0 +1,44 @@
+using Lucene.Net.Util;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Lucene.Net.Facet.Encoding
+{
+    public sealed class UniqueValuesIntEncoder : IntEncoderFilter
+    {
+        public UniqueValuesIntEncoder(IntEncoder encoder)
+            : base(encoder)
+        {
+        }
+
+        public override void Encode(IntsRef values, BytesRef buf)
+        {
+            int prev = values.ints[values.offset];
+            int idx = values.offset + 1;
+            int upto = values.offset + values.length;
+            for (int i = idx; i < upto; i++)
+            {
+                if (values.ints[i] != prev)
+                {
+                    values.ints[idx++] = values.ints[i];
+                    prev = values.ints[i];
+                }
+            }
+
+            values.length = idx - values.offset;
+            encoder.Encode(values, buf);
+        }
+
+        public override IntDecoder CreateMatchingDecoder()
+        {
+            return encoder.CreateMatchingDecoder();
+        }
+
+        public override string ToString()
+        {
+            return @"Unique(" + encoder.ToString() + @")";
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/9184d142/src/contrib/Facet/Params/CategoryListParams.cs
----------------------------------------------------------------------
diff --git a/src/contrib/Facet/Params/CategoryListParams.cs b/src/contrib/Facet/Params/CategoryListParams.cs
new file mode 100644
index 0000000..0671c42
--- /dev/null
+++ b/src/contrib/Facet/Params/CategoryListParams.cs
@@ -0,0 +1,84 @@
+using Lucene.Net.Facet.Encoding;
+using Lucene.Net.Facet.Search;
+using Lucene.Net.Facet.Util;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Lucene.Net.Facet.Params
+{
+    public class CategoryListParams
+    {
+        public enum OrdinalPolicy
+        {
+            NO_PARENTS,
+            ALL_PARENTS,
+            ALL_BUT_DIMENSION
+        }
+
+        public static readonly string DEFAULT_FIELD = "$facets";
+        public static readonly OrdinalPolicy DEFAULT_ORDINAL_POLICY = OrdinalPolicy.ALL_BUT_DIMENSION;
+        public readonly string field;
+        private readonly int hashCode;
+
+        public CategoryListParams()
+            : this(DEFAULT_FIELD)
+        {
+        }
+
+        public CategoryListParams(string field)
+        {
+            this.field = field;
+            this.hashCode = field.GetHashCode();
+        }
+
+        public virtual IntEncoder CreateEncoder()
+        {
+            return new SortingIntEncoder(new UniqueValuesIntEncoder(new DGapVInt8IntEncoder()));
+        }
+
+        public override bool Equals(Object o)
+        {
+            if (o == this)
+            {
+                return true;
+            }
+
+            if (!(o is CategoryListParams))
+            {
+                return false;
+            }
+
+            CategoryListParams other = (CategoryListParams)o;
+            if (hashCode != other.hashCode)
+            {
+                return false;
+            }
+
+            return field.Equals(other.field);
+        }
+
+        public override int GetHashCode()
+        {
+            return hashCode;
+        }
+
+        public virtual ICategoryListIterator CreateCategoryListIterator(int partition)
+        {
+            string categoryListTermStr = PartitionsUtils.PartitionName(partition);
+            string docValuesField = field + categoryListTermStr;
+            return new DocValuesCategoryListIterator(docValuesField, CreateEncoder().CreateMatchingDecoder());
+        }
+
+        public virtual OrdinalPolicy GetOrdinalPolicy(string dimension)
+        {
+            return DEFAULT_ORDINAL_POLICY;
+        }
+
+        public override string ToString()
+        {
+            return @"field=" + field + @" encoder=" + CreateEncoder() + @" ordinalPolicy=" + GetOrdinalPolicy(null);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/9184d142/src/contrib/Facet/Params/FacetIndexingParams.cs
----------------------------------------------------------------------
diff --git a/src/contrib/Facet/Params/FacetIndexingParams.cs b/src/contrib/Facet/Params/FacetIndexingParams.cs
new file mode 100644
index 0000000..1a4bee3
--- /dev/null
+++ b/src/contrib/Facet/Params/FacetIndexingParams.cs
@@ -0,0 +1,115 @@
+using Lucene.Net.Facet.Taxonomy;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Lucene.Net.Facet.Params
+{
+    public class FacetIndexingParams
+    {
+        protected static readonly CategoryListParams DEFAULT_CATEGORY_LIST_PARAMS = new CategoryListParams();
+        public static readonly FacetIndexingParams DEFAULT = new FacetIndexingParams();
+        public static readonly char DEFAULT_FACET_DELIM_CHAR = '';
+        private readonly int partitionSize = int.MaxValue;
+        protected readonly CategoryListParams clParams;
+
+        public FacetIndexingParams()
+            : this(DEFAULT_CATEGORY_LIST_PARAMS)
+        {
+        }
+
+        public FacetIndexingParams(CategoryListParams categoryListParams)
+        {
+            clParams = categoryListParams;
+        }
+
+        public virtual CategoryListParams GetCategoryListParams(CategoryPath category)
+        {
+            return clParams;
+        }
+
+        public virtual int DrillDownTermText(CategoryPath path, char[] buffer)
+        {
+            return path.CopyFullPath(buffer, 0, FacetDelimChar);
+        }
+
+        public virtual int PartitionSize
+        {
+            get
+            {
+                return partitionSize;
+            }
+        }
+
+        public virtual IList<CategoryListParams> AllCategoryListParams
+        {
+            get
+            {
+                return new[] { clParams };
+            }
+        }
+
+        public override int GetHashCode()
+        {
+            int prime = 31;
+            int result = 1;
+            result = prime * result + ((clParams == null) ? 0 : clParams.GetHashCode());
+            result = prime * result + partitionSize;
+            foreach (CategoryListParams clp in AllCategoryListParams)
+            {
+                result ^= clp.GetHashCode();
+            }
+
+            return result;
+        }
+
+        public override bool Equals(Object obj)
+        {
+            if (this == obj)
+            {
+                return true;
+            }
+
+            if (obj == null)
+            {
+                return false;
+            }
+
+            if (!(obj is FacetIndexingParams))
+            {
+                return false;
+            }
+
+            FacetIndexingParams other = (FacetIndexingParams)obj;
+            if (clParams == null)
+            {
+                if (other.clParams != null)
+                {
+                    return false;
+                }
+            }
+            else if (!clParams.Equals(other.clParams))
+            {
+                return false;
+            }
+
+            if (partitionSize != other.partitionSize)
+            {
+                return false;
+            }
+
+            IEnumerable<CategoryListParams> cLs = AllCategoryListParams;
+            IEnumerable<CategoryListParams> otherCLs = other.AllCategoryListParams;
+            return cLs.Equals(otherCLs);
+        }
+
+        public virtual char FacetDelimChar
+        {
+            get
+            {
+                return DEFAULT_FACET_DELIM_CHAR;
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/9184d142/src/contrib/Facet/Search/DocValuesCategoryListIterator.cs
----------------------------------------------------------------------
diff --git a/src/contrib/Facet/Search/DocValuesCategoryListIterator.cs b/src/contrib/Facet/Search/DocValuesCategoryListIterator.cs
new file mode 100644
index 0000000..a1aac91
--- /dev/null
+++ b/src/contrib/Facet/Search/DocValuesCategoryListIterator.cs
@@ -0,0 +1,68 @@
+using Lucene.Net.Facet.Encoding;
+using Lucene.Net.Index;
+using Lucene.Net.Util;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Lucene.Net.Facet.Search
+{
+    public class DocValuesCategoryListIterator : ICategoryListIterator
+    {
+        private readonly IntDecoder decoder;
+        private readonly string field;
+        private readonly int hashCode;
+        private readonly BytesRef bytes = new BytesRef(32);
+        private BinaryDocValues current;
+
+        public DocValuesCategoryListIterator(string field, IntDecoder decoder)
+        {
+            this.field = field;
+            this.decoder = decoder;
+            this.hashCode = field.GetHashCode();
+        }
+
+        public override int GetHashCode()
+        {
+            return hashCode;
+        }
+
+        public override bool Equals(Object o)
+        {
+            if (!(o is DocValuesCategoryListIterator))
+            {
+                return false;
+            }
+
+            DocValuesCategoryListIterator other = (DocValuesCategoryListIterator)o;
+            if (hashCode != other.hashCode)
+            {
+                return false;
+            }
+
+            return field.Equals(other.field);
+        }
+
+        public bool SetNextReader(AtomicReaderContext context)
+        {
+            current = context.AtomicReader.GetBinaryDocValues(field);
+            return current != null;
+        }
+
+        public void GetOrdinals(int docID, IntsRef ints)
+        {
+            current.Get(docID, bytes);
+            ints.length = 0;
+            if (bytes.length > 0)
+            {
+                decoder.Decode(bytes, ints);
+            }
+        }
+
+        public override string ToString()
+        {
+            return field;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/9184d142/src/contrib/Facet/Search/FacetResultNode.cs
----------------------------------------------------------------------
diff --git a/src/contrib/Facet/Search/FacetResultNode.cs b/src/contrib/Facet/Search/FacetResultNode.cs
new file mode 100644
index 0000000..aea9212
--- /dev/null
+++ b/src/contrib/Facet/Search/FacetResultNode.cs
@@ -0,0 +1,49 @@
+using Lucene.Net.Facet.Taxonomy;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Lucene.Net.Facet.Search
+{
+    public class FacetResultNode
+    {
+        public static readonly IList<FacetResultNode> EMPTY_SUB_RESULTS = new List<FacetResultNode>();
+        public int ordinal;
+        public CategoryPath label;
+        public double value;
+        public IList<FacetResultNode> subResults = EMPTY_SUB_RESULTS;
+
+        public FacetResultNode(int ordinal, double value)
+        {
+            this.ordinal = ordinal;
+            this.value = value;
+        }
+
+        public override string ToString()
+        {
+            return ToString("");
+        }
+
+        public virtual string ToString(string prefix)
+        {
+            StringBuilder sb = new StringBuilder(prefix);
+            if (label == null)
+            {
+                sb.Append("not labeled (ordinal=").Append(ordinal).Append(")");
+            }
+            else
+            {
+                sb.Append(label.ToString());
+            }
+
+            sb.Append(" (").Append(value.ToString()).Append(")");
+            foreach (FacetResultNode sub in subResults)
+            {
+                sb.Append("\n").Append(prefix).Append(sub.ToString(prefix + "  "));
+            }
+
+            return sb.ToString();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/9184d142/src/contrib/Facet/Search/ICategoryListIterator.cs
----------------------------------------------------------------------
diff --git a/src/contrib/Facet/Search/ICategoryListIterator.cs b/src/contrib/Facet/Search/ICategoryListIterator.cs
new file mode 100644
index 0000000..c182553
--- /dev/null
+++ b/src/contrib/Facet/Search/ICategoryListIterator.cs
@@ -0,0 +1,16 @@
+using Lucene.Net.Index;
+using Lucene.Net.Util;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Lucene.Net.Facet.Search
+{
+    public interface ICategoryListIterator
+    {
+        bool SetNextReader(AtomicReaderContext context);
+
+        void GetOrdinals(int docID, IntsRef ints);
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/9184d142/src/contrib/Facet/Search/IHeap.cs
----------------------------------------------------------------------
diff --git a/src/contrib/Facet/Search/IHeap.cs b/src/contrib/Facet/Search/IHeap.cs
new file mode 100644
index 0000000..67315ab
--- /dev/null
+++ b/src/contrib/Facet/Search/IHeap.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Lucene.Net.Facet.Search
+{
+    public interface IHeap<T>
+    {
+        T Pop();
+        T Top();
+        T InsertWithOverflow(T value);
+        T Add(T frn);
+        void Clear();
+        int Size { get; }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/9184d142/src/contrib/Facet/Search/IScoredDocIDs.cs
----------------------------------------------------------------------
diff --git a/src/contrib/Facet/Search/IScoredDocIDs.cs b/src/contrib/Facet/Search/IScoredDocIDs.cs
new file mode 100644
index 0000000..d884232
--- /dev/null
+++ b/src/contrib/Facet/Search/IScoredDocIDs.cs
@@ -0,0 +1,17 @@
+using Lucene.Net.Search;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Lucene.Net.Facet.Search
+{
+    public interface IScoredDocIDs
+    {
+        IScoredDocIDsIterator Iterator();
+
+        DocIdSet DocIDs { get; }
+        
+        int Size { get; }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/9184d142/src/contrib/Facet/Search/IScoredDocIDsIterator.cs
----------------------------------------------------------------------
diff --git a/src/contrib/Facet/Search/IScoredDocIDsIterator.cs b/src/contrib/Facet/Search/IScoredDocIDsIterator.cs
new file mode 100644
index 0000000..42cc668
--- /dev/null
+++ b/src/contrib/Facet/Search/IScoredDocIDsIterator.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Lucene.Net.Facet.Search
+{
+    public interface IScoredDocIDsIterator
+    {
+        /** Iterate to the next document/score pair. Returns true iff there is such a pair. */
+        bool Next();
+
+        /** Returns the ID of the current document. */
+        int DocID { get; }
+
+        /** Returns the score of the current document. */
+        float Score { get; }
+
+    }
+
+    public static class ScoredDocIDsIterator
+    {
+        /** Default score used in case scoring is disabled. */
+        public const float DEFAULT_SCORE = 1.0f;
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/9184d142/src/contrib/Facet/Util/FacetsPayloadMigrationReader.cs
----------------------------------------------------------------------
diff --git a/src/contrib/Facet/Util/FacetsPayloadMigrationReader.cs b/src/contrib/Facet/Util/FacetsPayloadMigrationReader.cs
new file mode 100644
index 0000000..d63ca89
--- /dev/null
+++ b/src/contrib/Facet/Util/FacetsPayloadMigrationReader.cs
@@ -0,0 +1,206 @@
+using Lucene.Net.Facet.Params;
+using Lucene.Net.Index;
+using Lucene.Net.Search;
+using Lucene.Net.Support;
+using Lucene.Net.Util;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+
+namespace Lucene.Net.Facet.Util
+{
+    public class FacetsPayloadMigrationReader : FilterAtomicReader
+    {
+        private class PayloadMigratingBinaryDocValues : BinaryDocValues
+        {
+            private Fields fields;
+            private Term term;
+            private DocsAndPositionsEnum dpe;
+            private int curDocID = -1;
+            private int lastRequestedDocID;
+            private DocsAndPositionsEnum GetDPE()
+            {
+                try
+                {
+                    DocsAndPositionsEnum dpe = null;
+                    if (fields != null)
+                    {
+                        Terms terms = fields.Terms(term.Field);
+                        if (terms != null)
+                        {
+                            TermsEnum te = terms.Iterator(null);
+                            if (te.SeekExact(term.Bytes, true))
+                            {
+                                dpe = te.DocsAndPositions(null, null, DocsAndPositionsEnum.FLAG_PAYLOADS);
+                            }
+                        }
+                    }
+
+                    return dpe;
+                }
+                catch (IOException ioe)
+                {
+                    throw;
+                }
+            }
+
+            internal PayloadMigratingBinaryDocValues(Fields fields, Term term)
+            {
+                this.fields = fields;
+                this.term = term;
+                this.dpe = GetDPE();
+                if (dpe == null)
+                {
+                    curDocID = DocIdSetIterator.NO_MORE_DOCS;
+                }
+                else
+                {
+                    try
+                    {
+                        curDocID = dpe.NextDoc();
+                    }
+                    catch (IOException e)
+                    {
+                        throw;
+                    }
+                }
+            }
+
+            public override void Get(int docID, BytesRef result)
+            {
+                try
+                {
+                    if (docID <= lastRequestedDocID)
+                    {
+                        dpe = GetDPE();
+                        if (dpe == null)
+                        {
+                            curDocID = DocIdSetIterator.NO_MORE_DOCS;
+                        }
+                        else
+                        {
+                            curDocID = dpe.NextDoc();
+                        }
+                    }
+
+                    lastRequestedDocID = docID;
+                    if (curDocID > docID)
+                    {
+                        result.length = 0;
+                        return;
+                    }
+
+                    if (curDocID < docID)
+                    {
+                        curDocID = dpe.Advance(docID);
+                        if (curDocID != docID)
+                        {
+                            result.length = 0;
+                            return;
+                        }
+                    }
+
+                    dpe.NextPosition();
+                    result.CopyBytes(dpe.Payload);
+                }
+                catch (IOException e)
+                {
+                    throw;
+                }
+            }
+        }
+
+        public static readonly string PAYLOAD_TERM_TEXT = @"$fulltree$";
+        public static IDictionary<String, Term> BuildFieldTermsMap(Lucene.Net.Store.Directory dir, FacetIndexingParams fip)
+        {
+            DirectoryReader reader = DirectoryReader.Open(dir);
+            IDictionary<String, Term> fieldTerms = new HashMap<String, Term>();
+            foreach (AtomicReaderContext context in reader.Leaves)
+            {
+                foreach (CategoryListParams clp in fip.AllCategoryListParams)
+                {
+                    Terms terms = context.AtomicReader.Terms(clp.field);
+                    if (terms != null)
+                    {
+                        TermsEnum te = terms.Iterator(null);
+                        BytesRef termBytes = null;
+                        while ((termBytes = te.Next()) != null)
+                        {
+                            string term = termBytes.Utf8ToString();
+                            if (term.StartsWith(PAYLOAD_TERM_TEXT))
+                            {
+                                if (term.Equals(PAYLOAD_TERM_TEXT))
+                                {
+                                    fieldTerms[clp.field] = new Term(clp.field, term);
+                                }
+                                else
+                                {
+                                    fieldTerms[clp.field + term.Substring(PAYLOAD_TERM_TEXT.Length)] = new Term(clp.field, term);
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+
+            reader.Dispose();
+            return fieldTerms;
+        }
+
+        private readonly IDictionary<String, Term> fieldTerms;
+
+        public FacetsPayloadMigrationReader(AtomicReader in_renamed, IDictionary<String, Term> fieldTerms)
+            : base(in_renamed)
+        {
+            this.fieldTerms = fieldTerms;
+        }
+
+        public override BinaryDocValues GetBinaryDocValues(string field)
+        {
+            Term term = fieldTerms[field];
+            if (term == null)
+            {
+                return base.GetBinaryDocValues(field);
+            }
+            else
+            {
+                return new PayloadMigratingBinaryDocValues(Fields, term);
+            }
+        }
+
+        public override FieldInfos FieldInfos
+        {
+            get
+            {
+                FieldInfos innerInfos = base.FieldInfos;
+                List<FieldInfo> infos = new List<FieldInfo>(innerInfos.Size);
+                HashSet<String> leftoverFields = new HashSet<String>(fieldTerms.Keys);
+                int number = -1;
+                foreach (FieldInfo info in innerInfos)
+                {
+                    if (fieldTerms.ContainsKey(info.name))
+                    {
+                        infos.Add(new FieldInfo(info.name, true, info.number, info.HasVectors, info.OmitsNorms, 
+                            info.HasPayloads, info.IndexOptionsValue, FieldInfo.DocValuesType.BINARY, info.NormType, info.Attributes));
+                        leftoverFields.Remove(info.name);
+                    }
+                    else
+                    {
+                        infos.Add(info);
+                    }
+
+                    number = Math.Max(number, info.number);
+                }
+
+                foreach (string field in leftoverFields)
+                {
+                    infos.Add(new FieldInfo(field, false, ++number, false, false, false, null, FieldInfo.DocValuesType.BINARY, null, null));
+                }
+
+                return new FieldInfos(infos.ToArray());
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/9184d142/src/contrib/Facet/Util/MultiCategoryListIterator.cs
----------------------------------------------------------------------
diff --git a/src/contrib/Facet/Util/MultiCategoryListIterator.cs b/src/contrib/Facet/Util/MultiCategoryListIterator.cs
new file mode 100644
index 0000000..40b24d1
--- /dev/null
+++ b/src/contrib/Facet/Util/MultiCategoryListIterator.cs
@@ -0,0 +1,51 @@
+using Lucene.Net.Facet.Search;
+using Lucene.Net.Index;
+using Lucene.Net.Util;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Lucene.Net.Facet.Util
+{
+    public class MultiCategoryListIterator : ICategoryListIterator
+    {
+        private readonly ICategoryListIterator[] iterators;
+        private readonly IList<ICategoryListIterator> validIterators;
+
+        public MultiCategoryListIterator(params ICategoryListIterator[] iterators)
+        {
+            this.iterators = iterators;
+            this.validIterators = new List<ICategoryListIterator>();
+        }
+
+        public bool SetNextReader(AtomicReaderContext context)
+        {
+            validIterators.Clear();
+            foreach (ICategoryListIterator cli in iterators)
+            {
+                if (cli.SetNextReader(context))
+                {
+                    validIterators.Add(cli);
+                }
+            }
+
+            return validIterators.Count > 0;
+        }
+
+        public void GetOrdinals(int docID, IntsRef ints)
+        {
+            IntsRef tmp = new IntsRef(ints.length);
+            foreach (ICategoryListIterator cli in validIterators)
+            {
+                cli.GetOrdinals(docID, tmp);
+                if (ints.ints.Length < ints.length + tmp.length)
+                {
+                    ints.Grow(ints.length + tmp.length);
+                }
+
+                ints.length += tmp.length;
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/9184d142/src/contrib/Facet/Util/OrdinalMappingAtomicReader.cs
----------------------------------------------------------------------
diff --git a/src/contrib/Facet/Util/OrdinalMappingAtomicReader.cs b/src/contrib/Facet/Util/OrdinalMappingAtomicReader.cs
new file mode 100644
index 0000000..55250d4
--- /dev/null
+++ b/src/contrib/Facet/Util/OrdinalMappingAtomicReader.cs
@@ -0,0 +1,86 @@
+using Lucene.Net.Facet.Encoding;
+using Lucene.Net.Facet.Params;
+using Lucene.Net.Index;
+using Lucene.Net.Support;
+using Lucene.Net.Util;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Lucene.Net.Facet.Util
+{
+    
+    public class OrdinalMappingAtomicReader : FilterAtomicReader
+    {
+        private readonly int[] ordinalMap;
+        private readonly IDictionary<String, CategoryListParams> dvFieldMap = new HashMap<String, CategoryListParams>();
+        
+        public OrdinalMappingAtomicReader(AtomicReader in_renamed, int[] ordinalMap)
+            : this (in_renamed, ordinalMap, FacetIndexingParams.DEFAULT)
+        {
+        }
+
+        public OrdinalMappingAtomicReader(AtomicReader in_renamed, int[] ordinalMap, FacetIndexingParams indexingParams)
+            : base (in_renamed)
+        {
+            this.ordinalMap = ordinalMap;
+            foreach (CategoryListParams params_renamed in indexingParams.AllCategoryListParams)
+            {
+                dvFieldMap[params_renamed.field] = params_renamed;
+            }
+        }
+
+        public override BinaryDocValues GetBinaryDocValues(string field)
+        {
+            BinaryDocValues inner = base.GetBinaryDocValues(field);
+            if (inner == null)
+            {
+                return inner;
+            }
+
+            CategoryListParams clp = dvFieldMap[field];
+            if (clp == null)
+            {
+                return inner;
+            }
+            else
+            {
+                return new OrdinalMappingBinaryDocValues(this, clp, inner);
+            }
+        }
+
+        private class OrdinalMappingBinaryDocValues : BinaryDocValues
+        {
+            private readonly IntEncoder encoder;
+            private readonly IntDecoder decoder;
+            private readonly IntsRef ordinals = new IntsRef(32);
+            private readonly BinaryDocValues delegate_renamed;
+            private readonly BytesRef scratch = new BytesRef();
+            private readonly OrdinalMappingAtomicReader parent;
+
+            internal OrdinalMappingBinaryDocValues(OrdinalMappingAtomicReader parent, CategoryListParams clp, BinaryDocValues delegate_renamed)
+            {
+                this.parent = parent;
+                this.delegate_renamed = delegate_renamed;
+                encoder = clp.CreateEncoder();
+                decoder = encoder.CreateMatchingDecoder();                
+            }
+
+            public override void Get(int docID, BytesRef result)
+            {
+                delegate_renamed.Get(docID, scratch);
+                if (scratch.length > 0)
+                {
+                    decoder.Decode(scratch, ordinals);
+                    for (int i = 0; i < ordinals.length; i++)
+                    {
+                        ordinals.ints[i] = parent.ordinalMap[ordinals.ints[i]];
+                    }
+
+                    encoder.Encode(ordinals, result);
+                }
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/9184d142/src/contrib/Facet/Util/PartitionsUtils.cs
----------------------------------------------------------------------
diff --git a/src/contrib/Facet/Util/PartitionsUtils.cs b/src/contrib/Facet/Util/PartitionsUtils.cs
new file mode 100644
index 0000000..3d18587
--- /dev/null
+++ b/src/contrib/Facet/Util/PartitionsUtils.cs
@@ -0,0 +1,40 @@
+using Lucene.Net.Facet.Params;
+using Lucene.Net.Facet.Taxonomy;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Lucene.Net.Facet.Util
+{
+    public static class PartitionsUtils
+    {
+        public const string PART_NAME_PREFIX = "$part";
+
+        public static int PartitionSize(FacetIndexingParams indexingParams, TaxonomyReader taxonomyReader)
+        {
+            return Math.Min(indexingParams.PartitionSize, taxonomyReader.Size);
+        }
+
+        public static int PartitionNumber(FacetIndexingParams iParams, int ordinal)
+        {
+            return ordinal / iParams.PartitionSize;
+        }
+
+        public static string PartitionNameByOrdinal(FacetIndexingParams iParams, int ordinal)
+        {
+            int partition = PartitionNumber(iParams, ordinal);
+            return PartitionName(partition);
+        }
+
+        public static string PartitionName(int partition)
+        {
+            if (partition == 0)
+            {
+                return "";
+            }
+
+            return PART_NAME_PREFIX + partition.ToString();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/9184d142/src/contrib/Facet/Util/PrintTaxonomyStats.cs
----------------------------------------------------------------------
diff --git a/src/contrib/Facet/Util/PrintTaxonomyStats.cs b/src/contrib/Facet/Util/PrintTaxonomyStats.cs
new file mode 100644
index 0000000..8b18d2c
--- /dev/null
+++ b/src/contrib/Facet/Util/PrintTaxonomyStats.cs
@@ -0,0 +1,89 @@
+using Lucene.Net.Facet.Taxonomy;
+using Lucene.Net.Facet.Taxonomy.Directory;
+using Lucene.Net.Store;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Lucene.Net.Facet.Util
+{
+    public class PrintTaxonomyStats
+    {
+        public static void Main(String[] args)
+        {
+            bool printTree = false;
+            string path = null;
+            for (int i = 0; i < args.Length; i++)
+            {
+                if (args[i].Equals("-printTree"))
+                {
+                    printTree = true;
+                }
+                else
+                {
+                    path = args[i];
+                }
+            }
+
+            if (args.Length != (printTree ? 2 : 1))
+            {
+                Console.Out.WriteLine("\nUsage: java -classpath ... org.apache.lucene.facet.util.PrintTaxonomyStats [-printTree] /path/to/taxononmy/index\n");
+                Environment.Exit(1);
+            }
+
+            Directory dir = FSDirectory.Open(path);
+            TaxonomyReader r = new DirectoryTaxonomyReader(dir);
+            PrintStats(r, Console.Out, printTree);
+            r.Dispose();
+            dir.Dispose();
+        }
+
+        public static void PrintStats(TaxonomyReader r, System.IO.TextWriter out_renamed, bool printTree)
+        {
+            out_renamed.WriteLine(r.Size + @" total categories.");
+            TaxonomyReader.ChildrenIterator it = r.GetChildren(TaxonomyReader.ROOT_ORDINAL);
+            int child;
+            while ((child = it.Next()) != TaxonomyReader.INVALID_ORDINAL)
+            {
+                TaxonomyReader.ChildrenIterator chilrenIt = r.GetChildren(child);
+                int numImmediateChildren = 0;
+                while (chilrenIt.Next() != TaxonomyReader.INVALID_ORDINAL)
+                {
+                    numImmediateChildren++;
+                }
+
+                CategoryPath cp = r.GetPath(child);
+                out_renamed.WriteLine(@"/" + cp + @": " + numImmediateChildren + @" immediate children; " + (1 + CountAllChildren(r, child)) + @" total categories");
+                if (printTree)
+                {
+                    PrintAllChildren(out_renamed, r, child, @"  ", 1);
+                }
+            }
+        }
+
+        private static int CountAllChildren(TaxonomyReader r, int ord)
+        {
+            int count = 0;
+            TaxonomyReader.ChildrenIterator it = r.GetChildren(ord);
+            int child;
+            while ((child = it.Next()) != TaxonomyReader.INVALID_ORDINAL)
+            {
+                count += 1 + CountAllChildren(r, child);
+            }
+
+            return count;
+        }
+
+        private static void PrintAllChildren(System.IO.TextWriter out_renamed, TaxonomyReader r, int ord, string indent, int depth)
+        {
+            TaxonomyReader.ChildrenIterator it = r.GetChildren(ord);
+            int child;
+            while ((child = it.Next()) != TaxonomyReader.INVALID_ORDINAL)
+            {
+                out_renamed.WriteLine(indent + @"/" + r.GetPath(child).components[depth]);
+                PrintAllChildren(out_renamed, r, child, indent + @"  ", depth + 1);
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/9184d142/src/contrib/Facet/Util/ResultSortUtils.cs
----------------------------------------------------------------------
diff --git a/src/contrib/Facet/Util/ResultSortUtils.cs b/src/contrib/Facet/Util/ResultSortUtils.cs
new file mode 100644
index 0000000..d186b95
--- /dev/null
+++ b/src/contrib/Facet/Util/ResultSortUtils.cs
@@ -0,0 +1,160 @@
+using Lucene.Net.Facet.Search;
+using Lucene.Net.Util;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Lucene.Net.Facet.Util
+{
+    public static class ResultSortUtils
+    {
+        public static IHeap<FacetResultNode> CreateSuitableHeap(FacetRequest facetRequest)
+        {
+            int nresults = facetRequest.numResults;
+            bool accending = (facetRequest.SortOrderValue == FacetRequest.SortOrder.ASCENDING);
+
+            if (nresults == int.MaxValue)
+            {
+                return new AllValueHeap(accending);
+            }
+
+            if (accending)
+            {
+                return new MaxValueHeap(nresults);
+            }
+            else
+            {
+                return new MinValueHeap(nresults);
+            }
+        }
+
+        private class MinValueHeap : PriorityQueue<FacetResultNode>, IHeap<FacetResultNode>
+        {
+            public MinValueHeap(int size)
+                : base(size)
+            {
+            }
+
+            public override bool LessThan(FacetResultNode arg0, FacetResultNode arg1)
+            {
+                double value0 = arg0.value;
+                double value1 = arg1.value;
+                int valueCompare = value0.CompareTo(value1);
+                if (valueCompare == 0)
+                {
+                    return arg0.ordinal < arg1.ordinal;
+                }
+
+                return valueCompare < 0;
+            }
+        }
+
+        private class MaxValueHeap : PriorityQueue<FacetResultNode>, IHeap<FacetResultNode>
+        {
+            public MaxValueHeap(int size)
+                : base(size)
+            {
+            }
+
+            public override bool LessThan(FacetResultNode arg0, FacetResultNode arg1)
+            {
+                double value0 = arg0.value;
+                double value1 = arg1.value;
+                int valueCompare = value0.CompareTo(value1);
+                if (valueCompare == 0)
+                {
+                    return arg0.ordinal > arg1.ordinal;
+                }
+
+                return valueCompare > 0;
+            }
+        }
+
+        private class AllValueHeap : IHeap<FacetResultNode>
+        {
+            private List<FacetResultNode> resultNodes = new List<FacetResultNode>();
+            readonly bool accending;
+            private bool isReady = false;
+
+            public AllValueHeap(bool accending)
+            {
+                this.accending = accending;
+            }
+
+            public FacetResultNode InsertWithOverflow(FacetResultNode node)
+            {
+                resultNodes.Add(node);
+                return null;
+            }
+
+            public FacetResultNode Pop()
+            {
+                if (!isReady)
+                {
+                    resultNodes.Sort(new AnonymousComparator(this));
+                    isReady = true;
+                }
+
+                var tmp = resultNodes[0];
+                resultNodes.RemoveAt(0);
+                return tmp;
+            }
+
+            private sealed class AnonymousComparator : IComparer<FacetResultNode>
+            {
+                public AnonymousComparator(AllValueHeap parent)
+                {
+                    this.parent = parent;
+                }
+
+                private readonly AllValueHeap parent;
+
+                public int Compare(FacetResultNode o1, FacetResultNode o2)
+                {
+                    int value = o1.value.CompareTo(o2.value);
+                    if (value == 0)
+                    {
+                        value = o1.ordinal - o2.ordinal;
+                    }
+
+                    if (parent.accending)
+                    {
+                        value = -value;
+                    }
+
+                    return value;
+                }
+            }
+
+            public int Size
+            {
+                get
+                {
+                    return resultNodes.Count;
+                }
+            }
+
+            public FacetResultNode Top()
+            {
+                if (resultNodes.Count > 0)
+                {
+                    return resultNodes[0];
+                }
+
+                return null;
+            }
+
+            public FacetResultNode Add(FacetResultNode frn)
+            {
+                resultNodes.Add(frn);
+                return null;
+            }
+
+            public void Clear()
+            {
+                resultNodes.Clear();
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/9184d142/src/contrib/Facet/Util/ScoredDocIdsUtils.cs
----------------------------------------------------------------------
diff --git a/src/contrib/Facet/Util/ScoredDocIdsUtils.cs b/src/contrib/Facet/Util/ScoredDocIdsUtils.cs
new file mode 100644
index 0000000..5570b25
--- /dev/null
+++ b/src/contrib/Facet/Util/ScoredDocIdsUtils.cs
@@ -0,0 +1,642 @@
+using Lucene.Net.Facet.Search;
+using Lucene.Net.Index;
+using Lucene.Net.Search;
+using Lucene.Net.Support;
+using Lucene.Net.Util;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+
+namespace Lucene.Net.Facet.Util
+{
+    public static class ScoredDocIdsUtils
+    {
+        public static IScoredDocIDs GetComplementSet(IScoredDocIDs docids, IndexReader reader)
+        {
+            int maxDoc = reader.MaxDoc;
+            DocIdSet docIdSet = docids.DocIDs;
+            FixedBitSet complement;
+            if (docIdSet is FixedBitSet)
+            {
+                complement = ((FixedBitSet)docIdSet).Clone();
+            }
+            else
+            {
+                complement = new FixedBitSet(maxDoc);
+                DocIdSetIterator iter = docIdSet.Iterator();
+                int doc;
+                while ((doc = iter.NextDoc()) < maxDoc)
+                {
+                    complement.Set(doc);
+                }
+            }
+
+            complement.Flip(0, maxDoc);
+            ClearDeleted(reader, complement);
+            return CreateScoredDocIds(complement, maxDoc);
+        }
+
+        private static void ClearDeleted(IndexReader reader, FixedBitSet set)
+        {
+            if (!reader.HasDeletions)
+            {
+                return;
+            }
+
+            DocIdSetIterator it = set.Iterator();
+            int doc = it.NextDoc();
+            foreach (AtomicReaderContext context in reader.Leaves)
+            {
+                AtomicReader r = context.AtomicReader;
+                int maxDoc = r.MaxDoc + context.docBase;
+                if (doc >= maxDoc)
+                {
+                    continue;
+                }
+
+                if (!r.HasDeletions)
+                {
+                    while ((doc = it.NextDoc()) < maxDoc)
+                    {
+                    }
+
+                    continue;
+                }
+
+                IBits liveDocs = r.LiveDocs;
+                do
+                {
+                    if (!liveDocs[doc - context.docBase])
+                    {
+                        set.Clear(doc);
+                    }
+                }
+                while ((doc = it.NextDoc()) < maxDoc);
+            }
+        }
+
+        public static IScoredDocIDs CreateScoredDocIDsSubset(IScoredDocIDs allDocIds, int[] sampleSet)
+        {
+            int[] docids = sampleSet;
+            Array.Sort(docids);
+            float[] scores = new float[docids.Length];
+            IScoredDocIDsIterator it = allDocIds.Iterator();
+            int n = 0;
+            while (it.Next() && n < docids.Length)
+            {
+                int doc = it.DocID;
+                if (doc == docids[n])
+                {
+                    scores[n] = it.Score;
+                    ++n;
+                }
+            }
+
+            int size = n;
+            return new AnonymousScoredDocIDs(size, docids, scores);
+        }
+
+        private sealed class AnonymousDocIdSetIterator : DocIdSetIterator
+        {
+            private int next = -1;
+
+            private readonly int size;
+            private readonly int[] docids;
+
+            public AnonymousDocIdSetIterator(int size, int[] docids)
+            {
+                this.size = size;
+                this.docids = docids;
+            }
+
+            public override int Advance(int target)
+            {
+                while (next < size && docids[next++] < target)
+                {
+                }
+
+                return next == size ? NO_MORE_DOCS : docids[next];
+            }
+
+            public override int DocID
+            {
+                get
+                {
+                    return docids[next];
+                }
+            }
+
+            public override int NextDoc()
+            {
+                if (++next >= size)
+                {
+                    return NO_MORE_DOCS;
+                }
+
+                return docids[next];
+            }
+
+            public override long Cost
+            {
+                get
+                {
+                    return size;
+                }
+            }
+        }
+
+        private sealed class AnonymousDocIdSet : DocIdSet
+        {
+            private readonly int size;
+            private readonly int[] docids;
+
+            public AnonymousDocIdSet(int size, int[] docids)
+            {
+                this.size = size;
+                this.docids = docids;
+            }
+
+            public override bool IsCacheable
+            {
+                get
+                {
+                    return true;
+                }
+            }
+
+            public override DocIdSetIterator Iterator()
+            {
+                return new AnonymousDocIdSetIterator(size, docids);
+            }
+        }
+
+        private sealed class AnonymousScoredDocIDsIterator : IScoredDocIDsIterator
+        {
+            int next = -1;
+
+            private readonly int size;
+            private readonly int[] docids;
+            private readonly float[] scores;
+
+            public AnonymousScoredDocIDsIterator(int size, int[] docids, float[] scores)
+            {
+                this.size = size;
+                this.docids = docids;
+                this.scores = scores;
+            }
+
+            public bool Next()
+            {
+                return ++next < size;
+            }
+
+            public float Score
+            {
+                get
+                {
+                    return scores[next];
+                }
+            }
+
+            public int DocID
+            {
+                get
+                {
+                    return docids[next];
+                }
+            }
+        }
+
+        private sealed class AnonymousScoredDocIDs : IScoredDocIDs
+        {
+            private readonly int size;
+            private readonly int[] docids;
+            private readonly float[] scores;
+
+            public AnonymousScoredDocIDs(int size, int[] docids, float[] scores)
+            {
+                this.size = size;
+                this.docids = docids;
+                this.scores = scores;
+            }
+
+            public DocIdSet DocIDs
+            {
+                get
+                {
+                    return new AnonymousDocIdSet(size, docids);
+                }
+            }
+
+            public IScoredDocIDsIterator Iterator()
+            {
+                return new AnonymousScoredDocIDsIterator(size, docids, scores);
+            }
+
+            public int Size
+            {
+                get
+                {
+                    return size;
+                }
+            }
+        }
+
+        public static IScoredDocIDs CreateAllDocsScoredDocIDs(IndexReader reader)
+        {
+            if (reader.HasDeletions)
+            {
+                return new AllLiveDocsScoredDocIDs(reader);
+            }
+
+            return new AllDocsScoredDocIDs(reader);
+        }
+
+        public static IScoredDocIDs CreateScoredDocIds(DocIdSet docIdSet, int maxDoc)
+        {
+            return new AnonymousScoredDocIDs1(docIdSet, maxDoc);
+        }
+
+        private sealed class AnonymousScoredDocIDsIterator1 : IScoredDocIDsIterator
+        {
+            public AnonymousScoredDocIDsIterator1(DocIdSetIterator docIterator)
+            {
+                this.docIterator = docIterator;
+            }
+
+            private readonly DocIdSetIterator docIterator;
+
+            public bool Next()
+            {
+                try
+                {
+                    return docIterator.NextDoc() != DocIdSetIterator.NO_MORE_DOCS;
+                }
+                catch (IOException e)
+                {
+                    throw;
+                }
+            }
+
+            public float Score
+            {
+                get
+                {
+                    return ScoredDocIDsIterator.DEFAULT_SCORE;
+                }
+            }
+
+            public int DocID
+            {
+                get
+                {
+                    return docIterator.DocID;
+                }
+            }
+        }
+
+        private sealed class AnonymousScoredDocIDs1 : IScoredDocIDs
+        {
+            public AnonymousScoredDocIDs1(DocIdSet docIdSet, int maxDoc)
+            {
+                this.docIdSet = docIdSet;
+                this.maxDoc = maxDoc;
+            }
+
+            private int size = -1;
+            private readonly DocIdSet docIdSet;
+            private readonly int maxDoc;
+
+            public DocIdSet DocIDs
+            {
+                get
+                {
+                    return docIdSet;
+                }
+            }
+
+            public IScoredDocIDsIterator Iterator()
+            {
+                DocIdSetIterator docIterator = docIdSet.Iterator();
+                return new AnonymousScoredDocIDsIterator1(docIterator);
+            }
+
+            public int Size
+            {
+                get
+                {
+                    if (size < 0)
+                    {
+                        OpenBitSetDISI openBitSetDISI;
+                        try
+                        {
+                            openBitSetDISI = new OpenBitSetDISI(docIdSet.Iterator(), maxDoc);
+                        }
+                        catch (IOException)
+                        {
+                            throw;
+                        }
+
+                        size = (int)openBitSetDISI.Cardinality;
+                    }
+
+                    return size;
+                }
+            }
+        }
+
+        private class AllDocsScoredDocIDs : IScoredDocIDs
+        {
+            readonly int maxDoc;
+            public AllDocsScoredDocIDs(IndexReader reader)
+            {
+                this.maxDoc = reader.MaxDoc;
+            }
+
+            public int Size
+            {
+                get
+                {
+                    return maxDoc;
+                }
+            }
+
+            public DocIdSet DocIDs
+            {
+                get
+                {
+                    return new AnonymousDocIdSet1(this);
+                }
+            }
+
+            private sealed class AnonymousDocIdSetIterator1 : DocIdSetIterator
+            {
+                public AnonymousDocIdSetIterator1(AllDocsScoredDocIDs parent)
+                {
+                    this.parent = parent;
+                }
+
+                private readonly AllDocsScoredDocIDs parent;
+                private int next = -1;
+
+                public override int Advance(int target)
+                {
+                    if (target <= next)
+                    {
+                        target = next + 1;
+                    }
+
+                    return next = target >= parent.maxDoc ? NO_MORE_DOCS : target;
+                }
+
+                public override int DocID
+                {
+                    get
+                    {
+                        return next;
+                    }
+                }
+
+                public override int NextDoc()
+                {
+                    return ++next < parent.maxDoc ? next : NO_MORE_DOCS;
+                }
+
+                public override long Cost
+                {
+                    get
+                    {
+                        return parent.maxDoc;
+                    }
+                }
+            }
+
+            private sealed class AnonymousDocIdSet1 : DocIdSet
+            {
+                public AnonymousDocIdSet1(AllDocsScoredDocIDs parent)
+                {
+                    this.parent = parent;
+                }
+
+                private readonly AllDocsScoredDocIDs parent;
+
+                public override bool IsCacheable
+                {
+                    get
+                    {
+                        return true;
+                    }
+                }
+
+                public override DocIdSetIterator Iterator()
+                {
+                    return new AnonymousDocIdSetIterator1(parent);
+                }
+            }
+
+            public IScoredDocIDsIterator Iterator()
+            {
+                try
+                {
+                    DocIdSetIterator iter = DocIDs.Iterator();
+                    return new AnonymousScoredDocIDsIterator2(iter);
+                }
+                catch (IOException)
+                {
+                    throw;
+                }
+            }
+
+            private sealed class AnonymousScoredDocIDsIterator2 : IScoredDocIDsIterator
+            {
+                public AnonymousScoredDocIDsIterator2(DocIdSetIterator iter)
+                {
+                    this.iter = iter;
+                }
+
+                private readonly DocIdSetIterator iter;
+
+                public bool Next()
+                {
+                    try
+                    {
+                        return iter.NextDoc() != DocIdSetIterator.NO_MORE_DOCS;
+                    }
+                    catch (IOException)
+                    {
+                        return false;
+                    }
+                }
+
+                public float Score
+                {
+                    get
+                    {
+                        return ScoredDocIDsIterator.DEFAULT_SCORE;
+                    }
+                }
+
+                public int DocID
+                {
+                    get
+                    {
+                        return iter.DocID;
+                    }
+                }
+            }
+        }
+
+        private sealed class AllLiveDocsScoredDocIDs : IScoredDocIDs
+        {
+            readonly int maxDoc;
+            readonly IndexReader reader;
+
+            internal AllLiveDocsScoredDocIDs(IndexReader reader)
+            {
+                this.maxDoc = reader.MaxDoc;
+                this.reader = reader;
+            }
+
+            public int Size
+            {
+                get
+                {
+                    return reader.NumDocs;
+                }
+            }
+
+            public DocIdSet DocIDs
+            {
+                get
+                {
+                    return new AnonymousDocIdSet2(this);
+                }
+            }
+
+            private sealed class AnonymousDocIdSetIterator2 : DocIdSetIterator
+            {
+                public AnonymousDocIdSetIterator2(AllLiveDocsScoredDocIDs parent)
+                {
+                    this.parent = parent;
+                    liveDocs = MultiFields.GetLiveDocs(parent.reader);
+                }
+
+                private readonly AllLiveDocsScoredDocIDs parent;
+                readonly IBits liveDocs; // = MultiFields.GetLiveDocs(parent.reader);
+                private int next = -1;
+
+                public override int Advance(int target)
+                {
+                    if (target > next)
+                    {
+                        next = target - 1;
+                    }
+
+                    return NextDoc();
+                }
+
+                public override int DocID
+                {
+                    get
+                    {
+                        return next;
+                    }
+                }
+
+                public override int NextDoc()
+                {
+                    do
+                    {
+                        ++next;
+                    }
+                    while (next < parent.maxDoc && liveDocs != null && !liveDocs[next]);
+                    return next < parent.maxDoc ? next : NO_MORE_DOCS;
+                }
+
+                public override long Cost
+                {
+                    get
+                    {
+                        return parent.maxDoc;
+                    }
+                }
+            }
+
+            private sealed class AnonymousDocIdSet2 : DocIdSet
+            {
+                public AnonymousDocIdSet2(AllLiveDocsScoredDocIDs parent)
+                {
+                    this.parent = parent;
+                }
+
+                private readonly AllLiveDocsScoredDocIDs parent;
+
+                public override bool IsCacheable
+                {
+                    get
+                    {
+                        return true;
+                    }
+                }
+
+                public override DocIdSetIterator Iterator()
+                {
+                    return new AnonymousDocIdSetIterator2(parent);
+                }
+            }
+
+            public IScoredDocIDsIterator Iterator()
+            {
+                try
+                {
+                    DocIdSetIterator iter = DocIDs.Iterator();
+                    return new AnonymousScoredDocIDsIterator3(iter);
+                }
+                catch (IOException e)
+                {
+                    throw;
+                }
+            }
+
+            private sealed class AnonymousScoredDocIDsIterator3 : IScoredDocIDsIterator
+            {
+                public AnonymousScoredDocIDsIterator3(DocIdSetIterator iter)
+                {
+                    this.iter = iter;
+                }
+
+                private readonly DocIdSetIterator iter;
+
+                public bool Next()
+                {
+                    try
+                    {
+                        return iter.NextDoc() != DocIdSetIterator.NO_MORE_DOCS;
+                    }
+                    catch (IOException)
+                    {
+                        return false;
+                    }
+                }
+
+                public float Score
+                {
+                    get
+                    {
+                        return ScoredDocIDsIterator.DEFAULT_SCORE;
+                    }
+                }
+
+                public int DocID
+                {
+                    get
+                    {
+                        return iter.DocID;
+                    }
+                }
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/9184d142/src/contrib/Facet/Util/TaxonomyMergeUtils.cs
----------------------------------------------------------------------
diff --git a/src/contrib/Facet/Util/TaxonomyMergeUtils.cs b/src/contrib/Facet/Util/TaxonomyMergeUtils.cs
new file mode 100644
index 0000000..18f926f
--- /dev/null
+++ b/src/contrib/Facet/Util/TaxonomyMergeUtils.cs
@@ -0,0 +1,40 @@
+using Lucene.Net.Facet.Params;
+using Lucene.Net.Facet.Taxonomy.Directory;
+using Lucene.Net.Index;
+using Lucene.Net.Store;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Lucene.Net.Facet.Util
+{
+    public static class TaxonomyMergeUtils
+    {
+        public static void Merge(Directory srcIndexDir, Directory srcTaxDir, DirectoryTaxonomyWriter.IOrdinalMap map, 
+            IndexWriter destIndexWriter, DirectoryTaxonomyWriter destTaxWriter, FacetIndexingParams params_renamed)
+        {
+            destTaxWriter.AddTaxonomy(srcTaxDir, map);
+            int[] ordinalMap = map.GetMap();
+            DirectoryReader reader = DirectoryReader.Open(srcIndexDir, -1);
+            IList<AtomicReaderContext> leaves = reader.Leaves;
+            int numReaders = leaves.Count;
+            AtomicReader[] wrappedLeaves = new AtomicReader[numReaders];
+            for (int i = 0; i < numReaders; i++)
+            {
+                wrappedLeaves[i] = new OrdinalMappingAtomicReader(leaves[i].AtomicReader, ordinalMap, params_renamed);
+            }
+
+            try
+            {
+                destIndexWriter.AddIndexes(new MultiReader(wrappedLeaves));
+                destTaxWriter.Commit();
+                destIndexWriter.Commit();
+            }
+            finally
+            {
+                reader.Dispose();
+            }
+        }
+    }
+}


Mime
View raw message