コード例 #1
0
ファイル: LongRangeCounter.cs プロジェクト: zfxsss/lucenenet
        private int rollup(LongRangeNode node, int[] counts, bool sawOutputs)
        {
            int count;

            sawOutputs |= node.outputs != null;
            if (node.left != null)
            {
                count  = rollup(node.left, counts, sawOutputs);
                count += rollup(node.right, counts, sawOutputs);
            }
            else
            {
                // Leaf:
                count = leafCounts[leafUpto];
                leafUpto++;
                if (!sawOutputs)
                {
                    // This is a missing count (no output ranges were
                    // seen "above" us):
                    missingCount += count;
                }
            }
            if (node.outputs != null)
            {
                foreach (int rangeIndex in node.outputs)
                {
                    counts[rangeIndex] += count;
                }
            }
            //System.out.println("  rollup node=" + node.start + " to " + node.end + ": count=" + count);
            return(count);
        }
コード例 #2
0
ファイル: LongRangeCounter.cs プロジェクト: zfxsss/lucenenet
 public LongRangeNode(long start, long end, LongRangeNode left, LongRangeNode right, int leafIndex)
 {
     this.start     = start;
     this.end       = end;
     this.left      = left;
     this.right     = right;
     this.leafIndex = leafIndex;
 }
コード例 #3
0
ファイル: LongRangeCounter.cs プロジェクト: zfxsss/lucenenet
 private static LongRangeNode Split(int start, int end, IList <InclusiveRange> elementaryIntervals)
 {
     if (start == end - 1)
     {
         // leaf
         InclusiveRange range = elementaryIntervals[start];
         return(new LongRangeNode(range.start, range.end, null, null, start));
     }
     else
     {
         int           mid   = (int)((uint)(start + end) >> 1);
         LongRangeNode left  = Split(start, mid, elementaryIntervals);
         LongRangeNode right = Split(mid, end, elementaryIntervals);
         return(new LongRangeNode(left.start, right.end, left, right, -1));
     }
 }
コード例 #4
0
ファイル: LongRangeCounter.cs プロジェクト: zfxsss/lucenenet
        public LongRangeCounter(LongRange[] ranges)
        {
            // Maps all range inclusive endpoints to int flags; 1
            // = start of interval, 2 = end of interval.  We need to
            // track the start vs end case separately because if a
            // given point is both, then it must be its own
            // elementary interval:
            IDictionary <long?, int?> endsMap = new Dictionary <long?, int?>();

            endsMap[long.MinValue] = 1;
            endsMap[long.MaxValue] = 2;

            foreach (LongRange range in ranges)
            {
                int?cur;
                if (!endsMap.TryGetValue(range.minIncl, out cur))
                {
                    endsMap[range.minIncl] = 1;
                }
                else
                {
                    endsMap[range.minIncl] = (int)cur | 1;
                }

                if (!endsMap.TryGetValue(range.maxIncl, out cur))
                {
                    endsMap[range.maxIncl] = 2;
                }
                else
                {
                    endsMap[range.maxIncl] = (int)cur | 2;
                }
            }

            var endsList = new List <long?>(endsMap.Keys);

            endsList.Sort();

            // Build elementaryIntervals (a 1D Venn diagram):
            IList <InclusiveRange> elementaryIntervals = new List <InclusiveRange>();
            int  upto0 = 1;
            long v     = endsList[0].HasValue ? endsList[0].Value : 0;
            long prev;

            if (endsMap[v] == 3)
            {
                elementaryIntervals.Add(new InclusiveRange(v, v));
                prev = v + 1;
            }
            else
            {
                prev = v;
            }

            while (upto0 < endsList.Count)
            {
                v = endsList[upto0].HasValue ?  endsList[upto0].Value : 0;
                int flags = endsMap[v].HasValue ? endsMap[v].Value : 0;
                //System.out.println("  v=" + v + " flags=" + flags);
                if (flags == 3)
                {
                    // This point is both an end and a start; we need to
                    // separate it:
                    if (v > prev)
                    {
                        elementaryIntervals.Add(new InclusiveRange(prev, v - 1));
                    }
                    elementaryIntervals.Add(new InclusiveRange(v, v));
                    prev = v + 1;
                }
                else if (flags == 1)
                {
                    // This point is only the start of an interval;
                    // attach it to next interval:
                    if (v > prev)
                    {
                        elementaryIntervals.Add(new InclusiveRange(prev, v - 1));
                    }
                    prev = v;
                }
                else
                {
                    Debug.Assert(flags == 2);
                    // This point is only the end of an interval; attach
                    // it to last interval:
                    elementaryIntervals.Add(new InclusiveRange(prev, v));
                    prev = v + 1;
                }
                //System.out.println("    ints=" + elementaryIntervals);
                upto0++;
            }

            // Build binary tree on top of intervals:
            root = Split(0, elementaryIntervals.Count, elementaryIntervals);

            // Set outputs, so we know which range to output for
            // each node in the tree:
            for (int i = 0; i < ranges.Length; i++)
            {
                root.addOutputs(i, ranges[i]);
            }

            // Set boundaries (ends of each elementary interval):
            boundaries = new long[elementaryIntervals.Count];
            for (int i = 0; i < boundaries.Length; i++)
            {
                boundaries[i] = elementaryIntervals[i].end;
            }

            leafCounts = new int[boundaries.Length];

            //System.out.println("ranges: " + Arrays.toString(ranges));
            //System.out.println("intervals: " + elementaryIntervals);
            //System.out.println("boundaries: " + Arrays.toString(boundaries));
            //System.out.println("root:\n" + root);
        }
コード例 #5
0
        public LongRangeCounter(LongRange[] ranges)
        {
            // Maps all range inclusive endpoints to int flags; 1
            // = start of interval, 2 = end of interval.  We need to
            // track the start vs end case separately because if a
            // given point is both, then it must be its own
            // elementary interval:
            IDictionary<long?, int?> endsMap = new Dictionary<long?, int?>();

            endsMap[long.MinValue] = 1;
            endsMap[long.MaxValue] = 2;

            foreach (LongRange range in ranges)
            {
                int? cur;
                if (!endsMap.TryGetValue(range.minIncl,out cur))
                {
                    endsMap[range.minIncl] = 1;
                }
                else
                {
                    endsMap[range.minIncl] = (int)cur | 1;
                }

                if (!endsMap.TryGetValue(range.maxIncl,out cur))
                {
                    endsMap[range.maxIncl] = 2;
                }
                else
                {
                    endsMap[range.maxIncl] = (int)cur | 2;
                }
            }

            var endsList = new List<long?>(endsMap.Keys);
            endsList.Sort();

            // Build elementaryIntervals (a 1D Venn diagram):
            IList<InclusiveRange> elementaryIntervals = new List<InclusiveRange>();
            int upto0 = 1;
            long v = endsList[0].HasValue ? endsList[0].Value : 0;
            long prev;
            if (endsMap[v] == 3)
            {
                elementaryIntervals.Add(new InclusiveRange(v, v));
                prev = v + 1;
            }
            else
            {
                prev = v;
            }

            while (upto0 < endsList.Count)
            {
                v = endsList[upto0].HasValue ?  endsList[upto0].Value : 0;
                int flags = endsMap[v].HasValue ? endsMap[v].Value : 0;
                //System.out.println("  v=" + v + " flags=" + flags);
                if (flags == 3)
                {
                    // This point is both an end and a start; we need to
                    // separate it:
                    if (v > prev)
                    {
                        elementaryIntervals.Add(new InclusiveRange(prev, v - 1));
                    }
                    elementaryIntervals.Add(new InclusiveRange(v, v));
                    prev = v + 1;
                }
                else if (flags == 1)
                {
                    // This point is only the start of an interval;
                    // attach it to next interval:
                    if (v > prev)
                    {
                        elementaryIntervals.Add(new InclusiveRange(prev, v - 1));
                    }
                    prev = v;
                }
                else
                {
                    Debug.Assert(flags == 2);
                    // This point is only the end of an interval; attach
                    // it to last interval:
                    elementaryIntervals.Add(new InclusiveRange(prev, v));
                    prev = v + 1;
                }
                //System.out.println("    ints=" + elementaryIntervals);
                upto0++;
            }

            // Build binary tree on top of intervals:
            root = Split(0, elementaryIntervals.Count, elementaryIntervals);

            // Set outputs, so we know which range to output for
            // each node in the tree:
            for (int i = 0; i < ranges.Length; i++)
            {
                root.addOutputs(i, ranges[i]);
            }

            // Set boundaries (ends of each elementary interval):
            boundaries = new long[elementaryIntervals.Count];
            for (int i = 0; i < boundaries.Length; i++)
            {
                boundaries[i] = elementaryIntervals[i].end;
            }

            leafCounts = new int[boundaries.Length];

            //System.out.println("ranges: " + Arrays.toString(ranges));
            //System.out.println("intervals: " + elementaryIntervals);
            //System.out.println("boundaries: " + Arrays.toString(boundaries));
            //System.out.println("root:\n" + root);
        }
コード例 #6
0
 public LongRangeNode(long start, long end, LongRangeNode left, LongRangeNode right, int leafIndex)
 {
     this.start = start;
     this.end = end;
     this.left = left;
     this.right = right;
     this.leafIndex = leafIndex;
 }
コード例 #7
0
 private int rollup(LongRangeNode node, int[] counts, bool sawOutputs)
 {
     int count;
     sawOutputs |= node.outputs != null;
     if (node.left != null)
     {
         count = rollup(node.left, counts, sawOutputs);
         count += rollup(node.right, counts, sawOutputs);
     }
     else
     {
         // Leaf:
         count = leafCounts[leafUpto];
         leafUpto++;
         if (!sawOutputs)
         {
             // This is a missing count (no output ranges were
             // seen "above" us):
             missingCount += count;
         }
     }
     if (node.outputs != null)
     {
         foreach (int rangeIndex in node.outputs)
         {
             counts[rangeIndex] += count;
         }
     }
     //System.out.println("  rollup node=" + node.start + " to " + node.end + ": count=" + count);
     return count;
 }