Port Facet.Associations

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

Branch: refs/heads/branch_4x
Commit: 38c33d54d01c0e05936410593bb3c78f2c6fc0b9
Parents: 4a21b96
Author: Paul Irwin <[email protected]>
Authored: Wed Nov 6 12:17:11 2013 -0500
Committer: Paul Irwin <[email protected]>
Committed: Wed Nov 6 12:17:11 2013 -0500

----------------------------------------------------------------------
 .../AssociationFloatSumFacetRequest.cs          | 30 ++++++++
 .../AssociationIntSumFacetRequest.cs            | 30 ++++++++
 .../Associations/AssociationsDrillDownStream.cs | 60 +++++++++++++++
 .../Associations/AssociationsFacetFields.cs     | 81 ++++++++++++++++++++
 .../Associations/AssociationsListBuilder.cs     | 58 ++++++++++++++
 .../CategoryAssociationsContainer.cs            | 44 +++++++++++
 .../Associations/CategoryFloatAssociation.cs    | 71 +++++++++++++++++
 .../Associations/CategoryIntAssociation.cs      | 70 +++++++++++++++++
 .../Facet/Associations/ICategoryAssociation.cs  | 19 +++++
 .../MultiAssociationsFacetsAggregator.cs        | 58 ++++++++++++++
 .../SumFloatAssociationFacetsAggregator.cs      | 61 +++++++++++++++
 .../SumIntAssociationFacetsAggregator.cs        | 60 +++++++++++++++
 src/contrib/Facet/Contrib.Facet.csproj          | 12 +++
 13 files changed, 654 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucenenet/blob/38c33d54/src/contrib/Facet/Associations/AssociationFloatSumFacetRequest.cs
----------------------------------------------------------------------
diff --git a/src/contrib/Facet/Associations/AssociationFloatSumFacetRequest.cs 
b/src/contrib/Facet/Associations/AssociationFloatSumFacetRequest.cs
new file mode 100644
index 0000000..3409dc6
--- /dev/null
+++ b/src/contrib/Facet/Associations/AssociationFloatSumFacetRequest.cs
@@ -0,0 +1,30 @@
+using Lucene.Net.Facet.Search;
+using Lucene.Net.Facet.Taxonomy;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Lucene.Net.Facet.Associations
+{
+    public class AssociationFloatSumFacetRequest : FacetRequest
+    {
+        public AssociationFloatSumFacetRequest(CategoryPath path, int num)
+            : base(path, num)
+        {
+        }
+
+        public override double GetValueOf(FacetArrays arrays, int ordinal)
+        {
+            return arrays.GetFloatArray()[ordinal];
+        }
+
+        public override FacetArraysSource FacetArraysSourceValue
+        {
+            get
+            {
+                return FacetArraysSource.FLOAT;
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/38c33d54/src/contrib/Facet/Associations/AssociationIntSumFacetRequest.cs
----------------------------------------------------------------------
diff --git a/src/contrib/Facet/Associations/AssociationIntSumFacetRequest.cs 
b/src/contrib/Facet/Associations/AssociationIntSumFacetRequest.cs
new file mode 100644
index 0000000..4579719
--- /dev/null
+++ b/src/contrib/Facet/Associations/AssociationIntSumFacetRequest.cs
@@ -0,0 +1,30 @@
+using Lucene.Net.Facet.Search;
+using Lucene.Net.Facet.Taxonomy;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Lucene.Net.Facet.Associations
+{
+    public class AssociationIntSumFacetRequest : FacetRequest
+    {
+        public AssociationIntSumFacetRequest(CategoryPath path, int num)
+            : base(path, num)
+        {
+        }
+
+        public override FacetArraysSource FacetArraysSourceValue
+        {
+            get
+            {
+                return FacetArraysSource.INT;
+            }
+        }
+
+        public override double GetValueOf(FacetArrays arrays, int ordinal)
+        {
+            return arrays.GetIntArray()[ordinal];
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/38c33d54/src/contrib/Facet/Associations/AssociationsDrillDownStream.cs
----------------------------------------------------------------------
diff --git a/src/contrib/Facet/Associations/AssociationsDrillDownStream.cs 
b/src/contrib/Facet/Associations/AssociationsDrillDownStream.cs
new file mode 100644
index 0000000..2976133
--- /dev/null
+++ b/src/contrib/Facet/Associations/AssociationsDrillDownStream.cs
@@ -0,0 +1,60 @@
+using Lucene.Net.Analysis.Tokenattributes;
+using Lucene.Net.Facet.Index;
+using Lucene.Net.Facet.Params;
+using Lucene.Net.Facet.Taxonomy;
+using Lucene.Net.Store;
+using Lucene.Net.Util;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Lucene.Net.Facet.Associations
+{
+    public class AssociationsDrillDownStream : DrillDownStream
+    {
+        private readonly IPayloadAttribute payloadAttribute;
+        private readonly BytesRef payload;
+        private readonly ByteArrayDataOutput output = new 
ByteArrayDataOutput();
+        private readonly CategoryAssociationsContainer associations;
+
+        public AssociationsDrillDownStream(CategoryAssociationsContainer 
associations, FacetIndexingParams indexingParams)
+            : base(associations, indexingParams)
+        {
+            this.associations = associations;
+            payloadAttribute = AddAttribute<IPayloadAttribute>();
+            BytesRef bytes = payloadAttribute.Payload;
+            if (bytes == null)
+            {
+                bytes = new BytesRef(new sbyte[4]);
+                payloadAttribute.Payload = bytes;
+            }
+
+            bytes.offset = 0;
+            this.payload = bytes;
+        }
+
+        protected override void AddAdditionalAttributes(CategoryPath cp, bool 
isParent)
+        {
+            if (isParent)
+            {
+                return;
+            }
+
+            ICategoryAssociation association = associations.GetAssociation(cp);
+            if (association == null)
+            {
+                return;
+            }
+
+            if (payload.bytes.Length < association.MaxBytesNeeded)
+            {
+                payload.Grow(association.MaxBytesNeeded);
+            }
+
+            output.Reset((byte[])(Array)payload.bytes);
+            association.Serialize(output);
+            payload.length = output.Position;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/38c33d54/src/contrib/Facet/Associations/AssociationsFacetFields.cs
----------------------------------------------------------------------
diff --git a/src/contrib/Facet/Associations/AssociationsFacetFields.cs 
b/src/contrib/Facet/Associations/AssociationsFacetFields.cs
new file mode 100644
index 0000000..6a26c4d
--- /dev/null
+++ b/src/contrib/Facet/Associations/AssociationsFacetFields.cs
@@ -0,0 +1,81 @@
+using Lucene.Net.Documents;
+using Lucene.Net.Facet.Index;
+using Lucene.Net.Facet.Params;
+using Lucene.Net.Facet.Taxonomy;
+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.Associations
+{
+    public class AssociationsFacetFields : FacetFields
+    {
+        private static readonly FieldType DRILL_DOWN_TYPE = new 
FieldType(TextField.TYPE_NOT_STORED);
+
+        static AssociationsFacetFields()
+        {
+            DRILL_DOWN_TYPE.IndexOptions = 
FieldInfo.IndexOptions.DOCS_AND_FREQS_AND_POSITIONS;
+            DRILL_DOWN_TYPE.Freeze();
+        }
+
+        public AssociationsFacetFields(ITaxonomyWriter taxonomyWriter)
+            : base(taxonomyWriter)
+        {
+        }
+
+        public AssociationsFacetFields(ITaxonomyWriter taxonomyWriter, 
FacetIndexingParams params_renamed)
+            : base(taxonomyWriter, params_renamed)
+        {
+        }
+
+        protected override IDictionary<CategoryListParams, 
IEnumerable<CategoryPath>> CreateCategoryListMapping(IEnumerable<CategoryPath> 
categories)
+        {
+            CategoryAssociationsContainer categoryAssociations = 
(CategoryAssociationsContainer)categories;
+            HashMap<CategoryListParams, IEnumerable<CategoryPath>> 
categoryLists = new HashMap<CategoryListParams, IEnumerable<CategoryPath>>();
+            foreach (CategoryPath cp in categories)
+            {
+                CategoryListParams clp = 
indexingParams.GetCategoryListParams(cp);
+                CategoryAssociationsContainer clpContainer = 
(CategoryAssociationsContainer)categoryLists[clp];
+                if (clpContainer == null)
+                {
+                    clpContainer = new CategoryAssociationsContainer();
+                    categoryLists[clp] = clpContainer;
+                }
+
+                clpContainer.SetAssociation(cp, 
categoryAssociations.GetAssociation(cp));
+            }
+
+            return categoryLists;
+        }
+
+        protected override IDictionary<string, BytesRef> 
GetCategoryListData(CategoryListParams categoryListParams, IntsRef ordinals, 
IEnumerable<CategoryPath> categories)
+        {
+            AssociationsListBuilder associations = new 
AssociationsListBuilder((CategoryAssociationsContainer)categories);
+            return associations.Build(ordinals, categories);
+        }
+
+        protected override DrillDownStream 
GetDrillDownStream(IEnumerable<CategoryPath> categories)
+        {
+            return new 
AssociationsDrillDownStream((CategoryAssociationsContainer)categories, 
indexingParams);
+        }
+
+        protected override FieldType DrillDownFieldType()
+        {
+            return DRILL_DOWN_TYPE;
+        }
+
+        public override void AddFields(Document doc, IEnumerable<CategoryPath> 
categories)
+        {
+            if (!(categories is CategoryAssociationsContainer))
+            {
+                throw new ArgumentException(@"categories must be of type " + 
typeof(CategoryAssociationsContainer).Name);
+            }
+
+            base.AddFields(doc, categories);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/38c33d54/src/contrib/Facet/Associations/AssociationsListBuilder.cs
----------------------------------------------------------------------
diff --git a/src/contrib/Facet/Associations/AssociationsListBuilder.cs 
b/src/contrib/Facet/Associations/AssociationsListBuilder.cs
new file mode 100644
index 0000000..107c031
--- /dev/null
+++ b/src/contrib/Facet/Associations/AssociationsListBuilder.cs
@@ -0,0 +1,58 @@
+using Lucene.Net.Facet.Index;
+using Lucene.Net.Facet.Taxonomy;
+using Lucene.Net.Store;
+using Lucene.Net.Support;
+using Lucene.Net.Util;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Lucene.Net.Facet.Associations
+{
+    public class AssociationsListBuilder : ICategoryListBuilder
+    {
+        private readonly CategoryAssociationsContainer associations;
+        private readonly ByteArrayDataOutput output = new 
ByteArrayDataOutput();
+
+        public AssociationsListBuilder(CategoryAssociationsContainer 
associations)
+        {
+            this.associations = associations;
+        }
+
+        public IDictionary<String, BytesRef> Build(IntsRef ordinals, 
IEnumerable<CategoryPath> categories)
+        {
+            HashMap<String, BytesRef> res = new HashMap<String, BytesRef>();
+            int idx = 0;
+            foreach (CategoryPath cp in categories)
+            {
+                ICategoryAssociation association = 
associations.GetAssociation(cp);
+                if (association == null)
+                {
+                    ++idx;
+                    continue;
+                }
+
+                BytesRef bytes = res[association.CategoryListID];
+                if (bytes == null)
+                {
+                    bytes = new BytesRef(32);
+                    res[association.CategoryListID] = bytes;
+                }
+
+                int maxBytesNeeded = 4 + association.MaxBytesNeeded + 
bytes.length;
+                if (bytes.bytes.Length < maxBytesNeeded)
+                {
+                    bytes.Grow(maxBytesNeeded);
+                }
+
+                output.Reset((byte[])(Array)bytes.bytes, bytes.length, 
bytes.bytes.Length - bytes.length);
+                output.WriteInt(ordinals.ints[idx++]);
+                association.Serialize(output);
+                bytes.length = output.Position;
+            }
+
+            return res;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/38c33d54/src/contrib/Facet/Associations/CategoryAssociationsContainer.cs
----------------------------------------------------------------------
diff --git a/src/contrib/Facet/Associations/CategoryAssociationsContainer.cs 
b/src/contrib/Facet/Associations/CategoryAssociationsContainer.cs
new file mode 100644
index 0000000..2e9ba8e
--- /dev/null
+++ b/src/contrib/Facet/Associations/CategoryAssociationsContainer.cs
@@ -0,0 +1,44 @@
+using Lucene.Net.Facet.Taxonomy;
+using Lucene.Net.Support;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Lucene.Net.Facet.Associations
+{
+    public class CategoryAssociationsContainer : IEnumerable<CategoryPath>
+    {
+        private readonly HashMap<CategoryPath, ICategoryAssociation> 
categoryAssociations = new HashMap<CategoryPath, ICategoryAssociation>();
+
+        public virtual void SetAssociation(CategoryPath category, 
ICategoryAssociation association)
+        {
+            categoryAssociations[category] = association;
+        }
+
+        public virtual ICategoryAssociation GetAssociation(CategoryPath 
category)
+        {
+            return categoryAssociations[category];
+        }
+
+        public IEnumerator<CategoryPath> GetEnumerator()
+        {
+            return categoryAssociations.Keys.GetEnumerator();
+        }
+
+        public virtual void Clear()
+        {
+            categoryAssociations.Clear();
+        }
+
+        public override string ToString()
+        {
+            return categoryAssociations.ToString();
+        }
+
+        System.Collections.IEnumerator 
System.Collections.IEnumerable.GetEnumerator()
+        {
+            return GetEnumerator();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/38c33d54/src/contrib/Facet/Associations/CategoryFloatAssociation.cs
----------------------------------------------------------------------
diff --git a/src/contrib/Facet/Associations/CategoryFloatAssociation.cs 
b/src/contrib/Facet/Associations/CategoryFloatAssociation.cs
new file mode 100644
index 0000000..112e799
--- /dev/null
+++ b/src/contrib/Facet/Associations/CategoryFloatAssociation.cs
@@ -0,0 +1,71 @@
+using Lucene.Net.Store;
+using Lucene.Net.Support;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+
+namespace Lucene.Net.Facet.Associations
+{
+    public class CategoryFloatAssociation : ICategoryAssociation
+    {
+        public static readonly string ASSOCIATION_LIST_ID = @"$assoc_float$";
+        private float value;
+
+        public CategoryFloatAssociation()
+        {
+        }
+
+        public CategoryFloatAssociation(float value)
+        {
+            this.value = value;
+        }
+
+        public void Serialize(ByteArrayDataOutput output)
+        {
+            try
+            {
+                output.WriteInt(Number.FloatToIntBits(value));
+            }
+            catch (IOException e)
+            {
+                throw new Exception(@"unexpected exception writing to a 
byte[]", e);
+            }
+        }
+
+        public void Deserialize(ByteArrayDataInput input)
+        {
+            value = Number.IntBitsToFloat(input.ReadInt());
+        }
+
+        public int MaxBytesNeeded
+        {
+            get
+            {
+                return 4;
+            }
+        }
+
+        public string CategoryListID
+        {
+            get
+            {
+                return ASSOCIATION_LIST_ID;
+            }
+        }
+
+        public virtual float Value
+        {
+            get
+            {
+                return value;
+            }
+        }
+
+        public override string ToString()
+        {
+            return GetType().Name + @"(" + value + @")";
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/38c33d54/src/contrib/Facet/Associations/CategoryIntAssociation.cs
----------------------------------------------------------------------
diff --git a/src/contrib/Facet/Associations/CategoryIntAssociation.cs 
b/src/contrib/Facet/Associations/CategoryIntAssociation.cs
new file mode 100644
index 0000000..cb2bde2
--- /dev/null
+++ b/src/contrib/Facet/Associations/CategoryIntAssociation.cs
@@ -0,0 +1,70 @@
+using Lucene.Net.Store;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+
+namespace Lucene.Net.Facet.Associations
+{
+    public class CategoryIntAssociation : ICategoryAssociation
+    {
+        public static readonly string ASSOCIATION_LIST_ID = @"$assoc_int$";
+        private int value;
+
+        public CategoryIntAssociation()
+        {
+        }
+
+        public CategoryIntAssociation(int value)
+        {
+            this.value = value;
+        }
+
+        public void Serialize(ByteArrayDataOutput output)
+        {
+            try
+            {
+                output.WriteInt(value);
+            }
+            catch (IOException e)
+            {
+                throw new Exception(@"unexpected exception writing to a 
byte[]", e);
+            }
+        }
+
+        public void Deserialize(ByteArrayDataInput input)
+        {
+            value = input.ReadInt();
+        }
+
+        public int MaxBytesNeeded
+        {
+            get
+            {
+                return 4;
+            }
+        }
+
+        public string CategoryListID
+        {
+            get
+            {
+                return ASSOCIATION_LIST_ID;
+            }
+        }
+
+        public virtual int Value
+        {
+            get
+            {
+                return value;
+            }
+        }
+
+        public override string ToString()
+        {
+            return GetType().Name + @"(" + value + @")";
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/38c33d54/src/contrib/Facet/Associations/ICategoryAssociation.cs
----------------------------------------------------------------------
diff --git a/src/contrib/Facet/Associations/ICategoryAssociation.cs 
b/src/contrib/Facet/Associations/ICategoryAssociation.cs
new file mode 100644
index 0000000..95a61ef
--- /dev/null
+++ b/src/contrib/Facet/Associations/ICategoryAssociation.cs
@@ -0,0 +1,19 @@
+using Lucene.Net.Store;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Lucene.Net.Facet.Associations
+{
+    public interface ICategoryAssociation
+    {
+        void Serialize(ByteArrayDataOutput output);
+        
+        void Deserialize(ByteArrayDataInput input);
+        
+        int MaxBytesNeeded { get; }
+
+        string CategoryListID { get; }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/38c33d54/src/contrib/Facet/Associations/MultiAssociationsFacetsAggregator.cs
----------------------------------------------------------------------
diff --git 
a/src/contrib/Facet/Associations/MultiAssociationsFacetsAggregator.cs 
b/src/contrib/Facet/Associations/MultiAssociationsFacetsAggregator.cs
new file mode 100644
index 0000000..cf0a14e
--- /dev/null
+++ b/src/contrib/Facet/Associations/MultiAssociationsFacetsAggregator.cs
@@ -0,0 +1,58 @@
+using Lucene.Net.Facet.Params;
+using Lucene.Net.Facet.Search;
+using Lucene.Net.Facet.Taxonomy;
+using Lucene.Net.Support;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Lucene.Net.Facet.Associations
+{
+    public class MultiAssociationsFacetsAggregator : IFacetsAggregator
+    {
+        private readonly IDictionary<CategoryPath, IFacetsAggregator> 
categoryAggregators;
+        private readonly List<IFacetsAggregator> aggregators;
+
+        public MultiAssociationsFacetsAggregator(IDictionary<CategoryPath, 
IFacetsAggregator> aggregators)
+        {
+            this.categoryAggregators = aggregators;
+            IDictionary<Type, IFacetsAggregator> aggsClasses = new 
HashMap<Type, IFacetsAggregator>();
+            foreach (IFacetsAggregator fa in aggregators.Values)
+            {
+                aggsClasses[fa.GetType()] = fa;
+            }
+
+            this.aggregators = new List<IFacetsAggregator>(aggsClasses.Values);
+        }
+
+        public void Aggregate(FacetsCollector.MatchingDocs matchingDocs, 
CategoryListParams clp, FacetArrays facetArrays)
+        {
+            foreach (IFacetsAggregator fa in aggregators)
+            {
+                fa.Aggregate(matchingDocs, clp, facetArrays);
+            }
+        }
+
+        public void RollupValues(FacetRequest fr, int ordinal, int[] children, 
int[] siblings, FacetArrays facetArrays)
+        {
+            categoryAggregators[fr.categoryPath].RollupValues(fr, ordinal, 
children, siblings, facetArrays);
+        }
+
+        public bool RequiresDocScores
+        {
+            get
+            {
+                foreach (IFacetsAggregator fa in aggregators)
+                {
+                    if (fa.RequiresDocScores)
+                    {
+                        return true;
+                    }
+                }
+
+                return false;
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/38c33d54/src/contrib/Facet/Associations/SumFloatAssociationFacetsAggregator.cs
----------------------------------------------------------------------
diff --git 
a/src/contrib/Facet/Associations/SumFloatAssociationFacetsAggregator.cs 
b/src/contrib/Facet/Associations/SumFloatAssociationFacetsAggregator.cs
new file mode 100644
index 0000000..0f452e5
--- /dev/null
+++ b/src/contrib/Facet/Associations/SumFloatAssociationFacetsAggregator.cs
@@ -0,0 +1,61 @@
+using Lucene.Net.Facet.Params;
+using Lucene.Net.Facet.Search;
+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.Associations
+{
+    public class SumFloatAssociationFacetsAggregator : IFacetsAggregator
+    {
+        private readonly BytesRef bytes = new BytesRef(32);
+
+        public void Aggregate(FacetsCollector.MatchingDocs matchingDocs, 
CategoryListParams clp, FacetArrays facetArrays)
+        {
+            BinaryDocValues dv = 
matchingDocs.context.AtomicReader.GetBinaryDocValues(clp.field + 
CategoryFloatAssociation.ASSOCIATION_LIST_ID);
+            if (dv == null)
+            {
+                return;
+            }
+
+            int length = matchingDocs.bits.Length;
+            float[] values = facetArrays.GetFloatArray();
+            int doc = 0;
+            while (doc < length && (doc = matchingDocs.bits.NextSetBit(doc)) 
!= -1)
+            {
+                dv.Get(doc, bytes);
+                if (bytes.length == 0)
+                {
+                    continue;
+                }
+
+                int bytesUpto = bytes.offset + bytes.length;
+                int pos = bytes.offset;
+                while (pos < bytesUpto)
+                {
+                    int ordinal = ((bytes.bytes[pos++] & 0xFF) << 24) | 
((bytes.bytes[pos++] & 0xFF) << 16) | ((bytes.bytes[pos++] & 0xFF) << 8) | 
(bytes.bytes[pos++] & 0xFF);
+                    int value = ((bytes.bytes[pos++] & 0xFF) << 24) | 
((bytes.bytes[pos++] & 0xFF) << 16) | ((bytes.bytes[pos++] & 0xFF) << 8) | 
(bytes.bytes[pos++] & 0xFF);
+                    values[ordinal] += Number.IntBitsToFloat(value);
+                }
+
+                ++doc;
+            }
+        }
+
+        public bool RequiresDocScores
+        {
+            get
+            {
+                return false;
+            }
+        }
+
+        public void RollupValues(FacetRequest fr, int ordinal, int[] children, 
int[] siblings, FacetArrays facetArrays)
+        {
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/38c33d54/src/contrib/Facet/Associations/SumIntAssociationFacetsAggregator.cs
----------------------------------------------------------------------
diff --git 
a/src/contrib/Facet/Associations/SumIntAssociationFacetsAggregator.cs 
b/src/contrib/Facet/Associations/SumIntAssociationFacetsAggregator.cs
new file mode 100644
index 0000000..5486e87
--- /dev/null
+++ b/src/contrib/Facet/Associations/SumIntAssociationFacetsAggregator.cs
@@ -0,0 +1,60 @@
+using Lucene.Net.Facet.Params;
+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.Associations
+{
+    public class SumIntAssociationFacetsAggregator : IFacetsAggregator
+    {
+        private readonly BytesRef bytes = new BytesRef(32);
+
+        public void Aggregate(FacetsCollector.MatchingDocs matchingDocs, 
CategoryListParams clp, FacetArrays facetArrays)
+        {
+            BinaryDocValues dv = 
matchingDocs.context.AtomicReader.GetBinaryDocValues(clp.field + 
CategoryIntAssociation.ASSOCIATION_LIST_ID);
+            if (dv == null)
+            {
+                return;
+            }
+
+            int length = matchingDocs.bits.Length;
+            int[] values = facetArrays.GetIntArray();
+            int doc = 0;
+            while (doc < length && (doc = matchingDocs.bits.NextSetBit(doc)) 
!= -1)
+            {
+                dv.Get(doc, bytes);
+                if (bytes.length == 0)
+                {
+                    continue;
+                }
+
+                int bytesUpto = bytes.offset + bytes.length;
+                int pos = bytes.offset;
+                while (pos < bytesUpto)
+                {
+                    int ordinal = ((bytes.bytes[pos++] & 0xFF) << 24) | 
((bytes.bytes[pos++] & 0xFF) << 16) | ((bytes.bytes[pos++] & 0xFF) << 8) | 
(bytes.bytes[pos++] & 0xFF);
+                    int value = ((bytes.bytes[pos++] & 0xFF) << 24) | 
((bytes.bytes[pos++] & 0xFF) << 16) | ((bytes.bytes[pos++] & 0xFF) << 8) | 
(bytes.bytes[pos++] & 0xFF);
+                    values[ordinal] += value;
+                }
+
+                ++doc;
+            }
+        }
+
+        public bool RequiresDocScores
+        {
+            get
+            {
+                return false;
+            }
+        }
+
+        public void RollupValues(FacetRequest fr, int ordinal, int[] children, 
int[] siblings, FacetArrays facetArrays)
+        {
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/38c33d54/src/contrib/Facet/Contrib.Facet.csproj
----------------------------------------------------------------------
diff --git a/src/contrib/Facet/Contrib.Facet.csproj 
b/src/contrib/Facet/Contrib.Facet.csproj
index 5e1acae..2bc69f5 100644
--- a/src/contrib/Facet/Contrib.Facet.csproj
+++ b/src/contrib/Facet/Contrib.Facet.csproj
@@ -43,6 +43,18 @@
     <Reference Include="System.Xml" />
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="Associations\AssociationFloatSumFacetRequest.cs" />
+    <Compile Include="Associations\AssociationIntSumFacetRequest.cs" />
+    <Compile Include="Associations\AssociationsDrillDownStream.cs" />
+    <Compile Include="Associations\AssociationsFacetFields.cs" />
+    <Compile Include="Associations\AssociationsListBuilder.cs" />
+    <Compile Include="Associations\CategoryFloatAssociation.cs" />
+    <Compile Include="Associations\CategoryIntAssociation.cs" />
+    <Compile Include="Associations\ICategoryAssociation.cs" />
+    <Compile Include="Associations\CategoryAssociationsContainer.cs" />
+    <Compile Include="Associations\MultiAssociationsFacetsAggregator.cs" />
+    <Compile Include="Associations\SumFloatAssociationFacetsAggregator.cs" />
+    <Compile Include="Associations\SumIntAssociationFacetsAggregator.cs" />
     <Compile Include="Codecs\Facet42\Facet42BinaryDocValues.cs" />
     <Compile Include="Codecs\Facet42\Facet42Codec.cs" />
     <Compile Include="Codecs\Facet42\Facet42DocValuesConsumer.cs" />

Reply via email to