Full Code of mbuchetics/RangeTree for AI

master acdcae6050b7 cached
22 files
61.6 KB
17.0k tokens
78 symbols
1 requests
Download .txt
Repository: mbuchetics/RangeTree
Branch: master
Commit: acdcae6050b7
Files: 22
Total size: 61.6 KB

Directory structure:
gitextract_7ydao9jy/

├── .gitattributes
├── .gitignore
├── CONTRIBUTORS.md
├── IntervalTree/
│   ├── IIntervalTree.cs
│   ├── IntervalTree.cs
│   ├── IntervalTree.csproj
│   ├── IntervalTreeNode.cs
│   └── RangeValuePair.cs
├── IntervalTree.sln
├── IntervalTreeExamples/
│   ├── IntervalTreeExamples.csproj
│   └── Program.cs
├── IntervalTreeTests/
│   ├── ComparerTests.cs
│   ├── IntervalTreeTests.cs
│   ├── IntervalTreeTests.csproj
│   ├── MultipleComparerTests.cs
│   ├── ReadmeExampleTests.cs
│   ├── TreeOfDateTimeTests.cs
│   ├── TreeOfIntTests.cs
│   └── TreeSpecs.cs
├── LICENSE.txt
├── README.md
└── rangetree.ruleset

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitattributes
================================================
###############################################################################
# Set default behavior to automatically normalize line endings.
###############################################################################
* text=auto

###############################################################################
# Set default behavior for command prompt diff.
#
# This is need for earlier builds of msysgit that does not have it on by
# default for csharp files.
# Note: This is only used by command line
###############################################################################
#*.cs     diff=csharp

###############################################################################
# Set the merge driver for project and solution files
#
# Merging from the command prompt will add diff markers to the files if there
# are conflicts (Merging from VS is not affected by the settings below, in VS
# the diff markers are never inserted). Diff markers may cause the following 
# file extensions to fail to load in VS. An alternative would be to treat
# these files as binary and thus will always conflict and require user
# intervention with every merge. To do so, just uncomment the entries below
###############################################################################
#*.sln       merge=binary
#*.csproj    merge=binary
#*.vbproj    merge=binary
#*.vcxproj   merge=binary
#*.vcproj    merge=binary
#*.dbproj    merge=binary
#*.fsproj    merge=binary
#*.lsproj    merge=binary
#*.wixproj   merge=binary
#*.modelproj merge=binary
#*.sqlproj   merge=binary
#*.wwaproj   merge=binary

###############################################################################
# behavior for image files
#
# image files are treated as binary by default.
###############################################################################
#*.jpg   binary
#*.png   binary
#*.gif   binary

###############################################################################
# diff behavior for common document formats
# 
# Convert binary document formats to text before diffing them. This feature
# is only available from the command line. Turn it on by uncommenting the 
# entries below.
###############################################################################
#*.doc   diff=astextplain
#*.DOC   diff=astextplain
#*.docx  diff=astextplain
#*.DOCX  diff=astextplain
#*.dot   diff=astextplain
#*.DOT   diff=astextplain
#*.pdf   diff=astextplain
#*.PDF   diff=astextplain
#*.rtf   diff=astextplain
#*.RTF   diff=astextplain


================================================
FILE: .gitignore
================================================
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.

# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates

# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs

!Source/SightPlayer.Omr.Test/x64/*.dll
!Source/SightPlayer.Omr.Test/x64/*.exe
!Source/SightPlayer.Omr.Test/x86/*.exe
!Source/SightPlayer.Omr.Test/x86/*.dll

# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
build/
bld/
[Bb]in/
[Oo]bj/

# Visual Studo 2015 cache/options directory
.vs/

# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*

# NUNIT
*.VisualState.xml
TestResult.xml

# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c

*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc

# Chutzpah Test files
_Chutzpah*

# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
*.cachefile

# Visual Studio profiler
*.psess
*.vsp
*.vspx

# TFS 2012 Local Workspace
$tf/

# Guidance Automation Toolkit
*.gpState

# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user

# JustCode is a .NET coding addin-in
.JustCode

# TeamCity is a build add-in
_TeamCity*

# DotCover is a Code Coverage Tool
*.dotCover

# NCrunch
_NCrunch_*
.*crunch*.local.xml

# MightyMoose
*.mm.*
AutoTest.Net/

# Web workbench (sass)
.sass-cache/

# Installshield output folder
[Ee]xpress/

# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html

# Click-Once directory
publish/

# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# TODO: Comment the next line if you want to checkin your web deploy settings 
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj

# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/packages/*
# except build/, which is used as an MSBuild target.
!**/packages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/packages/repositories.config

# Windows Azure Build Output
csx/
*.build.csdef

# Windows Store app package directory
AppPackages/

# Others
*Resource.Designer.cs
*.[Cc]ache
ClientBin/
[Ss]tyle[Cc]op.*
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.pfx
*.publishsettings
node_modules/
bower_components/

# RIA/Silverlight projects
Generated_Code/

# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm

# SQL Server files
*.mdf
*.ldf

# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings

# Microsoft Fakes
FakesAssemblies/

# Node.js Tools for Visual Studio
.ntvs_analysis.dat

# Visual Studio 6 build log
*.plg

# Visual Studio 6 workspace options file
*.opt

# Xamarin Components (will be restored like nuget packages)
Components

================================================
FILE: CONTRIBUTORS.md
================================================
Special thanks to the contributors

- [Steve Hansen](https://github.com/beefo)
- [Eric Domke](https://github.com/erdomke)
- [Jonas Nyrup](https://github.com/jnyrup)

================================================
FILE: IntervalTree/IIntervalTree.cs
================================================
using System.Collections.Generic;

namespace IntervalTree
{
    /// <summary>
    /// The standard interval tree implementation. Keeps a root node and forwards all queries to it.
    /// Whenever new items are added or items are removed, the tree goes temporarily "out of sync", which means that the
    /// internal index is not updated immediately, but upon the next query operation.    
    /// </summary>
    /// <typeparam name="TKey">The type of the range.</typeparam>
    /// <typeparam name="TValue">The type of the data items.</typeparam>
    public interface IIntervalTree<TKey, TValue> : IEnumerable<RangeValuePair<TKey, TValue>>
    {
        /// <summary>
        /// Returns all items contained in the tree.
        /// </summary>
        IEnumerable<TValue> Values { get; }

        /// <summary>
        /// Gets the number of elements contained in the tree.
        /// </summary>
        int Count { get; }

        /// <summary>
        /// Performs a point query with a single value. All items with overlapping ranges are returned.
        /// </summary>
        IEnumerable<TValue> Query(TKey value);

        /// <summary>
        /// Performs a range query. All items with overlapping ranges are returned.
        /// </summary>
        IEnumerable<TValue> Query(TKey from, TKey to);

        /// <summary>
        /// Adds the specified item.
        /// </summary>
        void Add(TKey from, TKey to, TValue value);

        /// <summary>
        /// Removes the specified item.
        /// </summary>
        void Remove(TValue item);

        /// <summary>
        /// Removes the specified items.
        /// </summary>
        void Remove(IEnumerable<TValue> items);

        /// <summary>
        /// Removes all elements from the range tree.
        /// </summary>
        void Clear();
    }
}

================================================
FILE: IntervalTree/IntervalTree.cs
================================================
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

namespace IntervalTree
{
    public class IntervalTree<TKey, TValue> : IIntervalTree<TKey, TValue>
    {
        private IntervalTreeNode<TKey, TValue> root;
        private List<RangeValuePair<TKey, TValue>> items;
        private readonly IComparer<TKey> comparer;
        private bool isInSync;

        IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();

        public TKey Max
        {
            get
            {
                if (!isInSync)
                    Rebuild();

                return root.Max;
            }
        }

        public TKey Min
        {
            get
            {
                if (!isInSync)
                    Rebuild();

                return root.Min;
            }
        }

        public IEnumerable<TValue> Values => items.Select(i => i.Value);

        public int Count => items.Count;

        /// <summary>
        /// Initializes an empty tree.
        /// </summary>
        public IntervalTree() : this(Comparer<TKey>.Default) { }

        /// <summary>
        /// Initializes an empty tree.
        /// </summary>
        public IntervalTree(IComparer<TKey> comparer)
        {
            this.comparer = comparer ?? Comparer<TKey>.Default;
            isInSync = true;
            root = new IntervalTreeNode<TKey, TValue>(this.comparer);
            items = new List<RangeValuePair<TKey, TValue>>();
        }

        public IEnumerable<TValue> Query(TKey value)
        {
            if (!isInSync)
                Rebuild();

            return root.Query(value);
        }

        public IEnumerable<TValue> Query(TKey from, TKey to)
        {
            if (!isInSync)
                Rebuild();

            return root.Query(from, to);
        }

        public void Add(TKey from, TKey to, TValue value)
        {
            if (comparer.Compare(from, to) > 0)
                throw new ArgumentOutOfRangeException($"{nameof(from)} cannot be larger than {nameof(to)}");

            isInSync = false;
            items.Add(new RangeValuePair<TKey, TValue>(from, to, value));
        }

        public void Remove(TValue value)
        {
            isInSync = false;
            items = items.Where(l => !l.Value.Equals(value)).ToList();
        }

        public void Remove(IEnumerable<TValue> items)
        {
            isInSync = false;
            this.items = this.items.Where(l => !items.Contains(l.Value)).ToList();
        }

        public void Clear()
        {
            root = new IntervalTreeNode<TKey, TValue>(comparer);
            items = new List<RangeValuePair<TKey, TValue>>();
            isInSync = true;
        }

        public IEnumerator<RangeValuePair<TKey, TValue>> GetEnumerator()
        {
            if (!isInSync)
                Rebuild();

            return items.GetEnumerator();
        }

        private void Rebuild()
        {
            if (isInSync)
                return;

            if (items.Count > 0)
                root = new IntervalTreeNode<TKey, TValue>(items, comparer);
            else
                root = new IntervalTreeNode<TKey, TValue>(comparer);
            isInSync = true;
        }
    }
}

================================================
FILE: IntervalTree/IntervalTree.csproj
================================================
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFrameworks>netstandard1.2;netstandard2.0;net45</TargetFrameworks>
    <PackageVersion>3.0.1</PackageVersion>
  </PropertyGroup>
  
  <PropertyGroup>
    <title>IntervalTree</title>
    <Description>A generic implementation of a centered interval tree in C#. 
In computer science, an interval tree is an ordered tree data structure to hold intervals. Specifically, it allows one to efficiently find all intervals that overlap with any given interval or point. It is often used for windowing queries, for instance, to find all roads on a computerized map inside a rectangular viewport, or to find all visible elements inside a three-dimensional scene.</Description>
    <GeneratePackageOnBuild>True</GeneratePackageOnBuild>
    <PackageRequireLicenseAcceptance>False</PackageRequireLicenseAcceptance>
    <Copyright>Copyright (c) 2020, Matthias Buchetics and Alexander Pacha</Copyright>
    <PackageLicenseUrl></PackageLicenseUrl>
    <PackageProjectUrl>https://github.com/mbuchetics/RangeTree</PackageProjectUrl>
    <RepositoryUrl>https://github.com/mbuchetics/RangeTree.git</RepositoryUrl>
    <RepositoryType>git</RepositoryType>
    <PackageTags>range, tree, interval</PackageTags>
    <Version>3.0.1</Version>
    <PackageId>RangeTree</PackageId>
    <Authors>Matthias Buchetics, Alexander Pacha and others, see CONTRIBUTORS.md</Authors>
    <Product>IntervalTree  - A generic interval tree implementation in C#</Product>
    <PackageReleaseNotes>This version contains a bug-fix for elements that have overlapping intervals. 
Thanks to @nordic81.

For a full list changes at https://github.com/mbuchetics/RangeTree/releases</PackageReleaseNotes>
    <AssemblyVersion>3.0.1</AssemblyVersion>
    <FileVersion>3.0.1</FileVersion>
    <Company>Matthias Buchetics, Alexander Pacha</Company>
  </PropertyGroup>
  
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
    <GenerateDocumentationFile>true</GenerateDocumentationFile>
  </PropertyGroup>

  <PropertyGroup>
    <CodeAnalysisRuleSet>$(SolutionDir)\rangetree.ruleset</CodeAnalysisRuleSet>
    <PackageLicenseFile>LICENSE.txt</PackageLicenseFile>
  </PropertyGroup>

  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
    <GenerateDocumentationFile>true</GenerateDocumentationFile>
  </PropertyGroup>

  <PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Release|netstandard1.2|AnyCPU'">
    <WarningLevel>3</WarningLevel>
  </PropertyGroup>

  <ItemGroup>
    <None Include="..\LICENSE.txt">
      <Pack>True</Pack>
      <PackagePath></PackagePath>
    </None>
  </ItemGroup>

</Project>


================================================
FILE: IntervalTree/IntervalTreeNode.cs
================================================
using System.Collections.Generic;

namespace IntervalTree
{
    /// <summary>
    ///     A node of the range tree. Given a list of items, it builds
    ///     its subtree. Also contains methods to query the subtree.
    ///     Basically, all interval tree logic is here.
    /// </summary>
    internal class IntervalTreeNode<TKey, TValue> : IComparer<RangeValuePair<TKey, TValue>>
    {
        private readonly TKey center;

        private readonly IComparer<TKey> comparer;
        private readonly RangeValuePair<TKey, TValue>[] items;
        private readonly IntervalTreeNode<TKey, TValue> leftNode;
        private readonly IntervalTreeNode<TKey, TValue> rightNode;

        /// <summary>
        ///     Initializes an empty node.
        /// </summary>
        /// <param name="comparer">The comparer used to compare two items.</param>
        public IntervalTreeNode(IComparer<TKey> comparer)
        {
            this.comparer = comparer ?? Comparer<TKey>.Default;

            center = default;
            leftNode = null;
            rightNode = null;
            items = null;
        }

        /// <summary>
        ///     Initializes a node with a list of items, builds the sub tree.
        /// </summary>
        /// <param name="items">The items that should be added to this node</param>
        /// <param name="comparer">The comparer used to compare two items.</param>
        public IntervalTreeNode(IList<RangeValuePair<TKey, TValue>> items, IComparer<TKey> comparer)
        {
            this.comparer = comparer ?? Comparer<TKey>.Default;

            // first, find the median
            var endPoints = new List<TKey>(items.Count * 2);
            foreach (var item in items)
            {
                endPoints.Add(item.From);
                endPoints.Add(item.To);
            }

            endPoints.Sort(this.comparer);

            // the median is used as center value
            if (endPoints.Count > 0)
            {
                Min = endPoints[0];
                center = endPoints[endPoints.Count / 2];
                Max = endPoints[endPoints.Count - 1];
            }

            var inner = new List<RangeValuePair<TKey, TValue>>();
            var left = new List<RangeValuePair<TKey, TValue>>();
            var right = new List<RangeValuePair<TKey, TValue>>();

            // iterate over all items
            // if the range of an item is completely left of the center, add it to the left items
            // if it is on the right of the center, add it to the right items
            // otherwise (range overlaps the center), add the item to this node's items
            foreach (var o in items)
                if (this.comparer.Compare(o.To, center) < 0)
                    left.Add(o);
                else if (this.comparer.Compare(o.From, center) > 0)
                    right.Add(o);
                else
                    inner.Add(o);

            // sort the items, this way the query is faster later on
            if (inner.Count > 0)
            {
                if (inner.Count > 1)
                    inner.Sort(this);
                this.items = inner.ToArray();
            }
            else
            {
                this.items = null;
            }

            // create left and right nodes, if there are any items
            if (left.Count > 0)
                leftNode = new IntervalTreeNode<TKey, TValue>(left, this.comparer);
            if (right.Count > 0)
                rightNode = new IntervalTreeNode<TKey, TValue>(right, this.comparer);
        }

        public TKey Max { get; }

        public TKey Min { get; }

        /// <summary>
        ///     Returns less than 0 if this range's From is less than the other, greater than 0 if greater.
        ///     If both are equal, the comparison of the To values is returned.
        ///     0 if both ranges are equal.
        /// </summary>
        /// <param name="x">The first item.</param>
        /// <param name="y">The other item.</param>
        /// <returns></returns>
        int IComparer<RangeValuePair<TKey, TValue>>.Compare(RangeValuePair<TKey, TValue> x,
            RangeValuePair<TKey, TValue> y)
        {
            var fromComp = comparer.Compare(x.From, y.From);
            if (fromComp == 0)
                return comparer.Compare(x.To, y.To);
            return fromComp;
        }

        /// <summary>
        ///     Performs a point query with a single value.
        ///     All items with overlapping ranges are returned.
        /// </summary>
        public IEnumerable<TValue> Query(TKey value)
        {
            var results = new List<TValue>();

            // If the node has items, check for leaves containing the value.
            if (items != null)
                foreach (var o in items)
                    if (comparer.Compare(o.From, value) > 0)
                        break;
                    else if (comparer.Compare(value, o.From) >= 0 && comparer.Compare(value, o.To) <= 0)
                        results.Add(o.Value);

            // go to the left or go to the right of the tree, depending
            // where the query value lies compared to the center
            var centerComp = comparer.Compare(value, center);
            if (leftNode != null && centerComp < 0)
                results.AddRange(leftNode.Query(value));
            else if (rightNode != null && centerComp > 0)
                results.AddRange(rightNode.Query(value));

            return results;
        }

        /// <summary>
        ///     Performs a range query.
        ///     All items with overlapping ranges are returned.
        /// </summary>
        public IEnumerable<TValue> Query(TKey from, TKey to)
        {
            var results = new List<TValue>();

            // If the node has items, check for leaves intersecting the range.
            if (items != null)
                foreach (var o in items)
                    if (comparer.Compare(o.From, to) > 0)
                        break;
                    else if (comparer.Compare(to, o.From) >= 0 && comparer.Compare(from, o.To) <= 0)
                        results.Add(o.Value);

            // go to the left or go to the right of the tree, depending
            // where the query value lies compared to the center
            if (leftNode != null && comparer.Compare(from, center) < 0)
                results.AddRange(leftNode.Query(from, to));
            if (rightNode != null && comparer.Compare(to, center) > 0)
                results.AddRange(rightNode.Query(from, to));

            return results;
        }
    }
}

================================================
FILE: IntervalTree/RangeValuePair.cs
================================================
using System;
using System.Collections.Generic;

namespace IntervalTree
{
    /// <summary>
    /// Represents a range of values.
    /// Both values must be of the same type and comparable.
    /// </summary>
    /// <typeparam name="TKey">Type of the values.</typeparam>
    public readonly struct RangeValuePair<TKey, TValue> : IEquatable<RangeValuePair<TKey, TValue>>
    {
        public TKey From { get; }
        public TKey To { get; }
        public TValue Value { get; }

        /// <summary>
        /// Initializes a new <see cref="RangeValuePair&lt;TKey, TValue&gt;"/> instance.
        /// </summary>
        public RangeValuePair(TKey from, TKey to, TValue value) : this()
        {
            From = from;
            To = to;
            Value = value;
        }

        /// <summary>
        /// Returns a <see cref="System.String"/> that represents this instance.
        /// </summary>
        /// <returns>
        /// A <see cref="System.String"/> that represents this instance.
        /// </returns>
        public override string ToString()
        {
            return string.Format("[{0} - {1}] {2}", From, To, Value);
        }

        public override int GetHashCode()
        {
            var hash = 23;
            if (From != null)
                hash = hash * 37 + From.GetHashCode();
            if (To != null)
                hash = hash * 37 + To.GetHashCode();
            if (Value != null)
                hash = hash * 37 + Value.GetHashCode();
            return hash;
        }

        public bool Equals(RangeValuePair<TKey, TValue> other)
        {
            return EqualityComparer<TKey>.Default.Equals(From, other.From)
                   && EqualityComparer<TKey>.Default.Equals(To, other.To)
                   && EqualityComparer<TValue>.Default.Equals(Value, other.Value);
        }

        public override bool Equals(object obj)
        {
            if (!(obj is RangeValuePair<TKey, TValue>))
                return false;

            return Equals((RangeValuePair<TKey, TValue>)obj);
        }

        public static bool operator ==(RangeValuePair<TKey, TValue> left, RangeValuePair<TKey, TValue> right)
        {
            return left.Equals(right);
        }

        public static bool operator !=(RangeValuePair<TKey, TValue> left, RangeValuePair<TKey, TValue> right)
        {
            return !(left == right);
        }
    }
}

================================================
FILE: IntervalTree.sln
================================================

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.30011.22
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IntervalTree", "IntervalTree\IntervalTree.csproj", "{A12CFD40-6EA9-459A-84AD-2DF944E332CE}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IntervalTreeExamples", "IntervalTreeExamples\IntervalTreeExamples.csproj", "{A2ECC374-8BB1-4B8C-AF67-062595E6FBDB}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IntervalTreeTests", "IntervalTreeTests\IntervalTreeTests.csproj", "{087BD1DE-623A-4C8B-A41B-E99938EC9296}"
EndProject
Global
	GlobalSection(SolutionConfigurationPlatforms) = preSolution
		Debug|Any CPU = Debug|Any CPU
		Release|Any CPU = Release|Any CPU
	EndGlobalSection
	GlobalSection(ProjectConfigurationPlatforms) = postSolution
		{A12CFD40-6EA9-459A-84AD-2DF944E332CE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{A12CFD40-6EA9-459A-84AD-2DF944E332CE}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{A12CFD40-6EA9-459A-84AD-2DF944E332CE}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{A12CFD40-6EA9-459A-84AD-2DF944E332CE}.Release|Any CPU.Build.0 = Release|Any CPU
		{A2ECC374-8BB1-4B8C-AF67-062595E6FBDB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{A2ECC374-8BB1-4B8C-AF67-062595E6FBDB}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{A2ECC374-8BB1-4B8C-AF67-062595E6FBDB}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{A2ECC374-8BB1-4B8C-AF67-062595E6FBDB}.Release|Any CPU.Build.0 = Release|Any CPU
		{087BD1DE-623A-4C8B-A41B-E99938EC9296}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{087BD1DE-623A-4C8B-A41B-E99938EC9296}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{087BD1DE-623A-4C8B-A41B-E99938EC9296}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{087BD1DE-623A-4C8B-A41B-E99938EC9296}.Release|Any CPU.Build.0 = Release|Any CPU
	EndGlobalSection
	GlobalSection(SolutionProperties) = preSolution
		HideSolutionNode = FALSE
	EndGlobalSection
	GlobalSection(ExtensibilityGlobals) = postSolution
		SolutionGuid = {ECFD1131-4EBD-489E-81BE-550DBF8805EF}
	EndGlobalSection
EndGlobal


================================================
FILE: IntervalTreeExamples/IntervalTreeExamples.csproj
================================================
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>netstandard1.6</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>
  </ItemGroup>

  <ItemGroup>
    <ProjectReference Include="..\IntervalTree\IntervalTree.csproj" />
  </ItemGroup>

  <PropertyGroup>
    <CodeAnalysisRuleSet>$(SolutionDir)\rangetree.ruleset</CodeAnalysisRuleSet>
    <ApplicationIcon />
    <OutputType>Exe</OutputType>
    <StartupObject />
  </PropertyGroup>

  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
    <DocumentationFile>bin\Release\netstandard1.3\RangeTree.Examples.xml</DocumentationFile>
  </PropertyGroup>

  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
    <DocumentationFile>bin\Debug\netstandard1.3\RangeTree.Examples.xml</DocumentationFile>
  </PropertyGroup>

</Project>

================================================
FILE: IntervalTreeExamples/Program.cs
================================================
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using IntervalTree;

namespace IntervalTreeExamples
{
    class Program
    {
        static void Main(string[] args)
        {
            TreeExample1();
            TreeExample2();
            Console.WriteLine("Press any key to continue...");
            Console.ReadKey();
        }

        static void TreeExample1()
        {
            Console.WriteLine("Example 1");

            var tree = new IntervalTree<int, string>()
            {
                { 0, 10, "1" },
                { 20, 30, "2" },
                { 15, 17, "3" },
                { 25, 35, "4" },
            };

            PrintQueryResult("query 1", tree.Query(5));
            PrintQueryResult("query 2", tree.Query(10));
            PrintQueryResult("query 3", tree.Query(29));
            PrintQueryResult("query 4", tree.Query(5, 15));

            Console.WriteLine();
        }

        static void TreeExample2()
        {
            Console.WriteLine("Example 2");

            var tree = new IntervalTree<int, string>();
            var stopwatch = new Stopwatch();
            stopwatch.Start();

            for (int i = 0; i < 100; i++)
            {
                for (int j = 0; j < 100; j++)
                {
                    RandomTreeInsert(tree, 1000);
                }

                var resultCount = tree.Query(50, 60).Count();
                Console.WriteLine("query: {0} results (tree count: {1})", resultCount, tree.Count);
            }

            stopwatch.Stop();
            Console.WriteLine("elapsed time: {0}", stopwatch.Elapsed);
        }

        static Random random = new Random();

        static void RandomTreeInsert(IIntervalTree<int, string> tree, int limit)
        {
            var a = random.Next(limit);
            var b = random.Next(limit);

            tree.Add(Math.Min(a, b), Math.Max(a, b), "value");
        }

        static void PrintQueryResult(string queryTitle, IEnumerable<string> result)
        {
            Console.WriteLine(queryTitle);
            foreach (var item in result)
            {
                Console.WriteLine(item);
            }
        }
    }
}


================================================
FILE: IntervalTreeTests/ComparerTests.cs
================================================
using System;
using System.Collections.Generic;
using IntervalTree;
using NUnit.Framework;

namespace IntervalTreeTests
{
    [TestFixture]
    public class ComparerTests
    {
        [Test]
        public void AddingAnItem_FromIsLargerThanTo_ShouldThrowException()
        {
            var comparer = Comparer<int>.Create((x, y) => x - y);
            var tree = new IntervalTree<int, string>(comparer);

            Assert.That(() => tree.Add(2, 0, "FOO"), Throws.InstanceOf<ArgumentOutOfRangeException>());
        }

        [Test]
        public void CreatingTreeWithNullComparer_AddingAnItem_ShouldNotThrowException()
        {
            var tree = new IntervalTree<int, string>(null);

            Assert.That(() => tree.Add(0, 1, "FOO"), Throws.Nothing);
        }
    }
}


================================================
FILE: IntervalTreeTests/IntervalTreeTests.cs
================================================
using NUnit.Framework;
using IntervalTree;

namespace IntervalTreeTests
{
    [TestFixture]
    public class IntervalTreeTests
    {
        [Test]
        public void GettingMin_InnerItems()
        {
            var tree = new IntervalTree<int, int>
            {
                { 1, 5, -1 },
                { 2, 5, -1 },
                { 3, 5, -1 },
            };

            var min = tree.Min;

            Assert.That(min, Is.EqualTo(1));
        }

        [Test]
        public void GettingMin_LeftRecurse()
        {
            var tree = new IntervalTree<int, int>
            {
                { 1, 2, -1 },
                { 3, 4, -1 }
            };

            var min = tree.Min;

            Assert.That(min, Is.EqualTo(1));
        }

        [Test]
        public void GettingMax_InnerItems()
        {
            var tree = new IntervalTree<int, int>
            {
                { 1, 2, -1 },
                { 1, 3, -1 },
                { 1, 4, -1 },
            };

            var max = tree.Max;

            Assert.That(max, Is.EqualTo(4));
        }

        [Test]
        public void GettingMax_RightRecurse()
        {
            var tree = new IntervalTree<int, int>
            {
                { 1, 2, -1 },
                { 3, 4, -1 },
                { 5, 6, -1 }
            };

            var max = tree.Max;

            Assert.That(max, Is.EqualTo(6));
        }

        [Test]
        public void GettingMin_Mixed()
        {
            var tree = new IntervalTree<int, int>
            {
                { 2, 3, -1 },
                { 8, 9, -1 },
                { 1, 10, -1 },
            };

            var min = tree.Min;

            Assert.That(min, Is.EqualTo(1));
        }
        
        [Test]
        public void GettingMax_Mixed()
        {
            var tree = new IntervalTree<int, int>
            {
                { 1, 10, -1 },
                { 2, 3, -1 },
                { 4, 5, -1 },
                { 8, 9, -1 },
            };

            var max = tree.Max;

            Assert.That(max, Is.EqualTo(10));
        }
    }
}


================================================
FILE: IntervalTreeTests/IntervalTreeTests.csproj
================================================
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>    
    <TargetFramework>netcoreapp2.1</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.6.1" />
    <PackageReference Include="NUnit" Version="3.12.0" />
    <PackageReference Include="NUnit3TestAdapter" Version="3.16.1">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>
  </ItemGroup>

  <ItemGroup>
    <ProjectReference Include="..\IntervalTree\IntervalTree.csproj" />
  </ItemGroup>

  <ItemGroup>
    <Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>
  </ItemGroup>

  <PropertyGroup>
    <CodeAnalysisRuleSet>$(SolutionDir)\rangetree.ruleset</CodeAnalysisRuleSet>
  </PropertyGroup>

  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
    <DocumentationFile>bin\Release\netcoreapp1.1\.xml</DocumentationFile>
    <WarningLevel>3</WarningLevel>
  </PropertyGroup>

  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
    <DocumentationFile>bin\Debug\netcoreapp1.1\.xml</DocumentationFile>
    <WarningLevel>3</WarningLevel>
  </PropertyGroup>

</Project>


================================================
FILE: IntervalTreeTests/MultipleComparerTests.cs
================================================
using System;
using System.Linq;
using NUnit.Framework;
using IntervalTree;

namespace IntervalTreeTests
{
    [TestFixture]
    public class MultipleComparerTests
    {
        [Test]
        public void CreateTwoTrees_ProvideDifferentComparers_ExpectBothToHaveTheComparersFromConstruction()
        {
            var tree = new IntervalTree<string, string>(StringComparer.Ordinal)
            {
                { "a", "e", "value1" },
                { "B", "D", "value2" },
            };
            var results = tree.Query("c").ToArray();
            Assert.That(results.Length, Is.EqualTo(1));
            Assert.That(results[0], Is.EqualTo("value1"));

            tree = new IntervalTree<string, string>(StringComparer.OrdinalIgnoreCase)
            {
                { "a", "e", "value1" },
                { "B", "D", "value2" },
            };
            results = tree.Query("c").ToArray();
            Assert.That(results.Length, Is.EqualTo(2));
            Assert.That(results[0], Is.EqualTo("value1"));
            Assert.That(results[1], Is.EqualTo("value2"));
        }
    }
}


================================================
FILE: IntervalTreeTests/ReadmeExampleTests.cs
================================================
using System.Linq;
using NUnit.Framework;
using IntervalTree;

namespace IntervalTreeTests
{
    [TestFixture]
    public class ReadmeExampleTests
    {
        [Test]
        public void Query_CreateTreeAndExecuteQuery_ExpectCorrectElementsToBeReturned()
        {
            var tree = new IntervalTree<int, string>()
            {
                { 0, 10, "1" },
                { 20, 30, "2" },
                { 15, 17, "3" },
                { 25, 35, "4" },
            };

            var results1 = tree.Query(5).ToArray();
            Assert.That(results1.Count, Is.EqualTo(1));
            Assert.That(results1[0], Is.EqualTo("1"));

            var results2 = tree.Query(10).ToArray();
            Assert.That(results2.Count, Is.EqualTo(1));
            Assert.That(results2[0], Is.EqualTo("1"));

            var results3 = tree.Query(29).ToArray();
            Assert.That(results3.Count, Is.EqualTo(2));
            Assert.That(results3[0], Is.EqualTo("2"));
            Assert.That(results3[1], Is.EqualTo("4"));

            var results4 = tree.Query(5, 15).ToArray();
            Assert.That(results4.Count, Is.EqualTo(2));
            Assert.That(results4[0], Is.EqualTo("3"));
            Assert.That(results4[1], Is.EqualTo("1"));
        }
    }
}


================================================
FILE: IntervalTreeTests/TreeOfDateTimeTests.cs
================================================
using System;
using System.Linq;
using NUnit.Framework;
using IntervalTree;

namespace IntervalTreeTests
{
    [TestFixture]
    internal class TreeOfDateTimeTests
    {
        private static readonly DateTime ZERO = new DateTime(2001, 01, 01, 10, 00, 00);

        [Test]
        public void BuildEmptyIntervalTree()
        {
            var emptyTree = new IntervalTree<DateTime, int>();
            Assert.Pass();
        }

        [Test]
        public void CreateEmptyIntervalTree()
        {
            var emptyTree = new IntervalTree<DateTime, int>();
            Assert.That(emptyTree, Is.Not.Null);
        }

        [Test]
        public void GetIntervalByExactEndTime()
        {
            var tree = new IntervalTree<DateTime, int>();
            tree.Add(ZERO, ZERO.AddHours(1), 100);

            var result = tree.Query(ZERO.AddHours(1)).ToList();
            Assert.That(result.Count, Is.EqualTo(1));
        }

        [Test]
        public void GetIntervalByExactStartTime()
        {
            var tree = new IntervalTree<DateTime, int>();
            tree.Add(ZERO, ZERO.AddHours(1), 100);

            var result = tree.Query(ZERO).ToList();
            Assert.That(result.Count, Is.EqualTo(1));
        }

        /// <summary>
        ///     0-----5-----10------15--------20
        ///     |=====100====|
        ///     |==200=|
        ///     |====300==========|
        /// </summary>
        [Test]
        public void OverlapOnExactEndAndStart_AssertCount()
        {
            var tree = new IntervalTree<DateTime, int>();
            tree.Add(ZERO, ZERO.AddHours(10), 100);
            tree.Add(ZERO.AddHours(10), ZERO.AddHours(15), 200);
            tree.Add(ZERO.AddHours(10), ZERO.AddHours(20), 200);

            var result = tree.Query(ZERO.AddHours(10)).ToList();
            Assert.That(result.Count, Is.EqualTo(3));
        }

        [Test]
        public void TestSeparateIntervals()
        {
            var tree = new IntervalTree<DateTime, int>();
            tree.Add(ZERO, ZERO.AddHours(10), 100);
            tree.Add(ZERO.AddHours(20), ZERO.AddHours(30), 200);

            var result = tree.Query(ZERO.AddHours(5)).ToList();
            Assert.That(result.Count, Is.EqualTo(1));
            Assert.That(result[0], Is.EqualTo(100));
        }

        [Test]
        public void TwoIntersectingIntervals()
        {
            var tree = new IntervalTree<DateTime, int>();
            tree.Add(ZERO, ZERO.AddHours(10), 100);
            tree.Add(ZERO.AddHours(3), ZERO.AddHours(30), 200);

            var result = tree.Query(ZERO.AddHours(5)).ToList();
            Assert.That(result.Count, Is.EqualTo(2));
            Assert.That(result[0], Is.EqualTo(100));
            Assert.That(result[1], Is.EqualTo(200));
        }
    }
}

================================================
FILE: IntervalTreeTests/TreeOfIntTests.cs
================================================
using System.Linq;
using NUnit.Framework;
using IntervalTree;

namespace IntervalTreeTests
{
    [TestFixture]
    internal class TreeOfIntTests
    {
        [Test]
        public void BuildEmptyIntervalTree()
        {
            var emptyTree = new IntervalTree<int, int>();
            Assert.Pass();
        }

        [Test]
        public void CreateEmptyIntervalTree()
        {
            var emptyTree = new IntervalTree<int, int>();
            Assert.That(emptyTree, Is.Not.Null);
        }

        [Test]
        public void TestSeparateIntervals()
        {
            var tree = new IntervalTree<int, int>();
            tree.Add(0, 10, 100);
            tree.Add(20, 30, 200);

            var result = tree.Query(5).ToList();
            Assert.That(result.Count, Is.EqualTo(1));
            Assert.That(result[0], Is.EqualTo(100));
        }

        [Test]
        public void TwoIntersectingIntervals()
        {
            var tree = new IntervalTree<int, int>();
            tree.Add(0, 10, 100);
            tree.Add(3, 30, 200);

            var result = tree.Query(5).ToList();
            Assert.That(result.Count, Is.EqualTo(2));
            Assert.That(result[0], Is.EqualTo(100));
            Assert.That(result[1], Is.EqualTo(200));
        }

        [Test]
        public void QueryOutOfSyncTree_ExpectObsoleteResults()
        {
            var tree = new IntervalTree<int, int>();
            tree.Add(0, 10, 100);

            var result = tree.Query(5).ToList();
            Assert.That(result.Count, Is.EqualTo(1));

            tree.Add(3, 30, 200);

            result = tree.Query(5).ToList();
            Assert.That(result.Count, Is.EqualTo(2));
        }
    }
}

================================================
FILE: IntervalTreeTests/TreeSpecs.cs
================================================
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using NUnit.Framework;
using IntervalTree;

namespace IntervalTreeTests
{
    [TestFixture]
    public class If_the_user_searches_for_overlapping_entries_in_an_interval_tree : Spec
    {
        private static IEnumerable<Tuple<int, int>> TestEntries()
        {
            yield return Tuple.Create(1400, 1500);
            yield return Tuple.Create(0100, 0130);
            yield return Tuple.Create(1700, 1800);
            yield return Tuple.Create(0230, 0240);
            yield return Tuple.Create(0530, 0540);
            yield return Tuple.Create(2330, 2400);
            yield return Tuple.Create(0700, 0800);
            yield return Tuple.Create(0900, 1000);
            yield return Tuple.Create(0000, 0100);
            yield return Tuple.Create(0540, 0700);
            yield return Tuple.Create(1800, 2130);
            yield return Tuple.Create(2130, 2131);
            yield return Tuple.Create(0200, 0230);
        }

        private static IEnumerable TestCases
        {
            get
            {
                yield return new TestCaseData(Tuple.Create(2000, 2300)).Returns(2);
                yield return new TestCaseData(Tuple.Create(0000, 0100)).Returns(2);
                yield return new TestCaseData(Tuple.Create(0000, 0000)).Returns(1);
                yield return new TestCaseData(Tuple.Create(0100, 0100)).Returns(2);
                yield return new TestCaseData(Tuple.Create(1000, 1100)).Returns(1);
                yield return new TestCaseData(Tuple.Create(1030, 1400)).Returns(1);
                yield return new TestCaseData(Tuple.Create(0150, 0155)).Returns(0);
                yield return new TestCaseData(Tuple.Create(2132, 2133)).Returns(0);
                yield return new TestCaseData(Tuple.Create(1030, 1350)).Returns(0);
                yield return new TestCaseData(Tuple.Create(0000, 2359)).Returns(13);
            }
        }

        [Test]
        [TestCaseSource("TestCases")]
        public int CorrectQuery_BuiltInOrder(Tuple<int, int> value)
        {
            var tree = CreateTree(TestEntries().OrderBy(interval => interval.Item1));
            return tree
                .Query(value.Item1, value.Item2)
                .Count();
        }

        [Test]
        [TestCaseSource("TestCases")]
        public int CorrectQuery_BuiltInReverseOrder(Tuple<int, int> value)
        {
            var tree = CreateTree(TestEntries().OrderBy(interval => interval.Item1).Reverse());
            return tree
                .Query(value.Item1, value.Item2)
                .Count();
        }

        [Test]
        [TestCaseSource("TestCases")]
        public int CorrectQuery_BuiltRandomly(Tuple<int, int> value)
        {
            var tree = CreateTree(TestEntries());
            return tree
                .Query(value.Item1, value.Item2)
                .Count();
        }

        private static IIntervalTree<int, string> CreateTree(IEnumerable<Tuple<int, int>> entries)
        {
            var tree = new IntervalTree<int, string>();

            foreach (var interval in entries)
            {
                tree.Add(interval.Item1, interval.Item2, "value");
            }

            return tree;
        }
    }

    /// <summary>
    /// Abstract helper class to make nunit tests more readable.
    /// </summary>
    [DebuggerStepThrough]
    [DebuggerNonUserCode]
    public class Spec
    {
        [DebuggerStepThrough]
        [OneTimeSetUp]
        public void SetUp()
        {
            EstablishContext();
            BecauseOf();
        }

        [DebuggerStepThrough]
        [OneTimeTearDown]
        public void TearDown()
        {
            Cleanup();
        }

        /// <summary>
        /// Test setup. Place your initialization code here.
        /// </summary>
        [DebuggerStepThrough]
        protected virtual void EstablishContext() { }

        /// <summary>
        /// Test run. Place the tested method / action here.
        /// </summary>
        [DebuggerStepThrough]
        protected virtual void BecauseOf() { }

        /// <summary>
        /// Test clean. Close/delete files, close database connections ..
        /// </summary>
        [DebuggerStepThrough]
        protected virtual void Cleanup() { }

        /// <summary>
        /// Creates an Action delegate.
        /// </summary>
        /// <param name="func">Method the shall be created as delegate.</param>
        /// <returns>A delegate of type <see cref="Action"/></returns>
        protected Action Invoking(Action func)
        {
            return func;
        }
    }
}


================================================
FILE: LICENSE.txt
================================================
If not noted otherwise in the file header, the project uses the MIT license.

Copyright (c) 2020, Matthias Buchetics and Alexander Pacha.

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

================================================
FILE: README.md
================================================
# IntervalTree #

[![Build status](https://ci.appveyor.com/api/projects/status/t8xvh5oquuvk17ks?svg=true)](https://ci.appveyor.com/project/apacha/rangetree)
[![NuGet version](https://img.shields.io/nuget/v/RangeTree.svg?style=flat-square)](https://www.nuget.org/packages/RangeTree)

## A generic interval tree ##

A generic implementation of a centered interval tree in C#. 

From [Wikipedia](http://en.wikipedia.org/wiki/Interval_tree):
> In computer science, an interval tree is an ordered tree data structure to hold intervals. Specifically, it allows one to efficiently find all intervals that overlap with any given interval or point. It is often used for windowing queries, for instance, to find all roads on a computerized map inside a rectangular viewport, or to find all visible elements inside a three-dimensional scene.

Based on the Java implementation found here: http://www.sanfoundry.com/java-program-implement-interval-tree/

Queries require `O(log n + m)` time, with `n` being the total number of intervals and `m` being the number of reported results. Construction requires `O(n log n)` time, and storage requires `O(n)` space.

### Requirements ###
- Consuming this NuGet package requires .NET Framework >= 4.5 or .NET Standard >= 1.2
- Developing this project requires Visual Studio 2017 with .NET Framework >= 4.5 and .NET Standard >= 2.0.

## Simple Interface ###

```csharp
public interface IIntervalTree<TKey, TValue> 
    : IEnumerable<RangeValuePair<TKey, TValue>>
{
    IEnumerable<TValue> Values { get; }
    int Count { get; }

    IEnumerable<TValue> Query(TKey value);
    IEnumerable<TValue> Query(TKey from, TKey to);

    void Add(TKey from, TKey to, TValue value);
    void Remove(TValue item);
    void Remove(IEnumerable<TValue> items);
    void Clear();
}
```
    
## Usage ###

```csharp
var tree = new IntervalTree<int, string>()
{
    { 0, 10, "1" },
    { 20, 30, "2" },
    { 15, 17, "3" },
    { 25, 35, "4" },
};

// Alternatively, use the Add method, for example:
// tree.Add(0, 10, "1");

var results1 = tree.Query(5);     // 1 item: [0 - 10]
var results2 = tree.Query(10);    // 1 item: [0 - 10]
var results3 = tree.Query(29);    // 2 items: [20 - 30], [25 - 35]
var results4 = tree.Query(5, 15); // 2 items: [0 - 10], [15 - 17]
```
    
The solution file contains more examples and tests, that show how to use IntervalTree with other data types.
    
## Implementation Details ##

In this implementation, whenever you add or remove items from the tree, the tree goes "out of sync" internally, which means that the items are stored, but the tree-index is not updated yet. Upon the next query, the tree structure is automatically rebuild. Subsequent queries will use the cached index and be much faster. The creation of the tree-index requires `O(n log n)` time. Therefore, it is best suited for trees that do not change often or small trees, where the creation time is negligible.

## RangeTree vs. IntervalTree ##

This project contains an IntervalTree (see [Issue #24](https://github.com/mbuchetics/RangeTree/issues/24)), but was incorrectly named RangeTree at the beginning. It was mostly renamed to IntervalTree in version 3.0.0. However, given that a large number of users are using this project, renaming the NuGet package and repository was not possible without breaking too much, so we settled with (just) renaming all occurences in the source code and documentation.

================================================
FILE: rangetree.ruleset
================================================
<?xml version="1.0" encoding="utf-8"?>
<RuleSet Name="RangeTree" Description="These rules focus on the most critical problems in your code, including potential security holes, application crashes, and other important logic and design errors. You should include this rule set in any custom rule set you create for your projects." ToolsVersion="15.0">
  <Rules AnalyzerId="CodeCracker.CSharp" RuleNamespace="CodeCracker.CSharp">
    <Rule Id="CC0001" Action="None" />
    <Rule Id="CC0091" Action="None" />
    <Rule Id="CC0105" Action="None" />
  </Rules>
  <Rules AnalyzerId="Microsoft.Analyzers.ManagedCodeAnalysis" RuleNamespace="Microsoft.Rules.Managed">
    <Rule Id="CA1001" Action="Warning" />
    <Rule Id="CA1002" Action="Warning" />
    <Rule Id="CA1003" Action="Warning" />
    <Rule Id="CA1004" Action="Warning" />
    <Rule Id="CA1005" Action="Warning" />
    <Rule Id="CA1006" Action="Warning" />
    <Rule Id="CA1007" Action="Warning" />
    <Rule Id="CA1008" Action="Warning" />
    <Rule Id="CA1009" Action="Warning" />
    <Rule Id="CA1010" Action="Warning" />
    <Rule Id="CA1011" Action="Warning" />
    <Rule Id="CA1012" Action="Warning" />
    <Rule Id="CA1013" Action="Warning" />
    <Rule Id="CA1014" Action="Warning" />
    <Rule Id="CA1016" Action="Warning" />
    <Rule Id="CA1017" Action="Warning" />
    <Rule Id="CA1018" Action="Warning" />
    <Rule Id="CA1019" Action="Warning" />
    <Rule Id="CA1020" Action="Warning" />
    <Rule Id="CA1021" Action="Warning" />
    <Rule Id="CA1023" Action="Warning" />
    <Rule Id="CA1024" Action="Warning" />
    <Rule Id="CA1025" Action="Warning" />
    <Rule Id="CA1026" Action="Warning" />
    <Rule Id="CA1027" Action="Warning" />
    <Rule Id="CA1028" Action="Warning" />
    <Rule Id="CA1030" Action="Warning" />
    <Rule Id="CA1031" Action="Warning" />
    <Rule Id="CA1032" Action="Warning" />
    <Rule Id="CA1033" Action="Warning" />
    <Rule Id="CA1034" Action="Warning" />
    <Rule Id="CA1035" Action="Warning" />
    <Rule Id="CA1036" Action="Warning" />
    <Rule Id="CA1038" Action="Warning" />
    <Rule Id="CA1039" Action="Warning" />
    <Rule Id="CA1040" Action="Warning" />
    <Rule Id="CA1041" Action="Warning" />
    <Rule Id="CA1043" Action="Warning" />
    <Rule Id="CA1044" Action="Warning" />
    <Rule Id="CA1045" Action="Warning" />
    <Rule Id="CA1046" Action="Warning" />
    <Rule Id="CA1047" Action="Warning" />
    <Rule Id="CA1048" Action="Warning" />
    <Rule Id="CA1049" Action="Warning" />
    <Rule Id="CA1050" Action="Warning" />
    <Rule Id="CA1051" Action="Warning" />
    <Rule Id="CA1052" Action="Warning" />
    <Rule Id="CA1053" Action="Warning" />
    <Rule Id="CA1054" Action="Warning" />
    <Rule Id="CA1055" Action="Warning" />
    <Rule Id="CA1056" Action="Warning" />
    <Rule Id="CA1057" Action="Warning" />
    <Rule Id="CA1058" Action="Warning" />
    <Rule Id="CA1059" Action="Warning" />
    <Rule Id="CA1060" Action="Warning" />
    <Rule Id="CA1061" Action="Warning" />
    <Rule Id="CA1062" Action="Warning" />
    <Rule Id="CA1063" Action="Warning" />
    <Rule Id="CA1064" Action="Warning" />
    <Rule Id="CA1065" Action="Warning" />
    <Rule Id="CA1300" Action="Warning" />
    <Rule Id="CA1301" Action="Warning" />
    <Rule Id="CA1302" Action="Warning" />
    <Rule Id="CA1303" Action="Warning" />
    <Rule Id="CA1304" Action="Warning" />
    <Rule Id="CA1305" Action="Warning" />
    <Rule Id="CA1306" Action="Warning" />
    <Rule Id="CA1307" Action="Warning" />
    <Rule Id="CA1308" Action="Warning" />
    <Rule Id="CA1309" Action="Warning" />
    <Rule Id="CA1400" Action="Warning" />
    <Rule Id="CA1401" Action="Warning" />
    <Rule Id="CA1402" Action="Warning" />
    <Rule Id="CA1403" Action="Warning" />
    <Rule Id="CA1404" Action="Warning" />
    <Rule Id="CA1405" Action="Warning" />
    <Rule Id="CA1406" Action="Warning" />
    <Rule Id="CA1407" Action="Warning" />
    <Rule Id="CA1408" Action="Warning" />
    <Rule Id="CA1409" Action="Warning" />
    <Rule Id="CA1410" Action="Warning" />
    <Rule Id="CA1411" Action="Warning" />
    <Rule Id="CA1412" Action="Warning" />
    <Rule Id="CA1413" Action="Warning" />
    <Rule Id="CA1414" Action="Warning" />
    <Rule Id="CA1415" Action="Warning" />
    <Rule Id="CA1500" Action="Warning" />
    <Rule Id="CA1501" Action="Warning" />
    <Rule Id="CA1502" Action="Warning" />
    <Rule Id="CA1504" Action="Warning" />
    <Rule Id="CA1505" Action="Warning" />
    <Rule Id="CA1506" Action="Warning" />
    <Rule Id="CA1600" Action="Warning" />
    <Rule Id="CA1601" Action="Warning" />
    <Rule Id="CA1700" Action="Warning" />
    <Rule Id="CA1701" Action="Warning" />
    <Rule Id="CA1702" Action="Warning" />
    <Rule Id="CA1703" Action="Warning" />
    <Rule Id="CA1704" Action="Warning" />
    <Rule Id="CA1707" Action="Warning" />
    <Rule Id="CA1708" Action="Warning" />
    <Rule Id="CA1709" Action="Warning" />
    <Rule Id="CA1710" Action="Warning" />
    <Rule Id="CA1711" Action="Warning" />
    <Rule Id="CA1712" Action="Warning" />
    <Rule Id="CA1713" Action="Warning" />
    <Rule Id="CA1714" Action="Warning" />
    <Rule Id="CA1715" Action="Warning" />
    <Rule Id="CA1716" Action="Warning" />
    <Rule Id="CA1717" Action="Warning" />
    <Rule Id="CA1719" Action="Warning" />
    <Rule Id="CA1720" Action="Warning" />
    <Rule Id="CA1721" Action="Warning" />
    <Rule Id="CA1722" Action="Warning" />
    <Rule Id="CA1724" Action="Warning" />
    <Rule Id="CA1725" Action="Warning" />
    <Rule Id="CA1726" Action="Warning" />
    <Rule Id="CA1800" Action="Warning" />
    <Rule Id="CA1801" Action="Warning" />
    <Rule Id="CA1802" Action="Warning" />
    <Rule Id="CA1804" Action="Warning" />
    <Rule Id="CA1806" Action="Warning" />
    <Rule Id="CA1809" Action="Warning" />
    <Rule Id="CA1810" Action="Warning" />
    <Rule Id="CA1811" Action="Warning" />
    <Rule Id="CA1812" Action="Warning" />
    <Rule Id="CA1813" Action="Warning" />
    <Rule Id="CA1814" Action="Warning" />
    <Rule Id="CA1815" Action="Warning" />
    <Rule Id="CA1816" Action="Warning" />
    <Rule Id="CA1819" Action="Warning" />
    <Rule Id="CA1820" Action="Warning" />
    <Rule Id="CA1821" Action="Warning" />
    <Rule Id="CA1822" Action="Warning" />
    <Rule Id="CA1823" Action="Warning" />
    <Rule Id="CA1824" Action="Warning" />
    <Rule Id="CA1900" Action="Warning" />
    <Rule Id="CA1901" Action="Warning" />
    <Rule Id="CA1903" Action="Warning" />
    <Rule Id="CA2000" Action="Warning" />
    <Rule Id="CA2001" Action="Warning" />
    <Rule Id="CA2002" Action="Warning" />
    <Rule Id="CA2003" Action="Warning" />
    <Rule Id="CA2004" Action="Warning" />
    <Rule Id="CA2006" Action="Warning" />
    <Rule Id="CA2100" Action="Warning" />
    <Rule Id="CA2101" Action="Warning" />
    <Rule Id="CA2102" Action="Warning" />
    <Rule Id="CA2103" Action="Warning" />
    <Rule Id="CA2104" Action="Warning" />
    <Rule Id="CA2105" Action="Warning" />
    <Rule Id="CA2106" Action="Warning" />
    <Rule Id="CA2107" Action="Warning" />
    <Rule Id="CA2108" Action="Warning" />
    <Rule Id="CA2109" Action="Warning" />
    <Rule Id="CA2111" Action="Warning" />
    <Rule Id="CA2112" Action="Warning" />
    <Rule Id="CA2114" Action="Warning" />
    <Rule Id="CA2115" Action="Warning" />
    <Rule Id="CA2116" Action="Warning" />
    <Rule Id="CA2117" Action="Warning" />
    <Rule Id="CA2118" Action="Warning" />
    <Rule Id="CA2119" Action="Warning" />
    <Rule Id="CA2120" Action="Warning" />
    <Rule Id="CA2121" Action="Warning" />
    <Rule Id="CA2122" Action="Warning" />
    <Rule Id="CA2123" Action="Warning" />
    <Rule Id="CA2124" Action="Warning" />
    <Rule Id="CA2126" Action="Warning" />
    <Rule Id="CA2130" Action="Warning" />
    <Rule Id="CA2131" Action="Warning" />
    <Rule Id="CA2132" Action="Warning" />
    <Rule Id="CA2133" Action="Warning" />
    <Rule Id="CA2134" Action="Warning" />
    <Rule Id="CA2135" Action="Warning" />
    <Rule Id="CA2136" Action="Warning" />
    <Rule Id="CA2137" Action="Warning" />
    <Rule Id="CA2138" Action="Warning" />
    <Rule Id="CA2139" Action="Warning" />
    <Rule Id="CA2140" Action="Warning" />
    <Rule Id="CA2141" Action="Warning" />
    <Rule Id="CA2142" Action="Warning" />
    <Rule Id="CA2143" Action="Warning" />
    <Rule Id="CA2144" Action="Warning" />
    <Rule Id="CA2145" Action="Warning" />
    <Rule Id="CA2146" Action="Warning" />
    <Rule Id="CA2147" Action="Warning" />
    <Rule Id="CA2149" Action="Warning" />
    <Rule Id="CA2151" Action="Warning" />
    <Rule Id="CA2200" Action="Warning" />
    <Rule Id="CA2201" Action="Warning" />
    <Rule Id="CA2202" Action="Warning" />
    <Rule Id="CA2204" Action="Warning" />
    <Rule Id="CA2205" Action="Warning" />
    <Rule Id="CA2207" Action="Warning" />
    <Rule Id="CA2208" Action="Warning" />
    <Rule Id="CA2210" Action="Warning" />
    <Rule Id="CA2211" Action="Warning" />
    <Rule Id="CA2212" Action="Warning" />
    <Rule Id="CA2213" Action="Warning" />
    <Rule Id="CA2214" Action="Warning" />
    <Rule Id="CA2215" Action="Warning" />
    <Rule Id="CA2216" Action="Warning" />
    <Rule Id="CA2217" Action="Warning" />
    <Rule Id="CA2218" Action="Warning" />
    <Rule Id="CA2219" Action="Warning" />
    <Rule Id="CA2220" Action="Warning" />
    <Rule Id="CA2221" Action="Warning" />
    <Rule Id="CA2222" Action="Warning" />
    <Rule Id="CA2223" Action="Warning" />
    <Rule Id="CA2224" Action="Warning" />
    <Rule Id="CA2225" Action="Warning" />
    <Rule Id="CA2226" Action="Warning" />
    <Rule Id="CA2227" Action="Warning" />
    <Rule Id="CA2228" Action="Warning" />
    <Rule Id="CA2229" Action="Warning" />
    <Rule Id="CA2230" Action="Warning" />
    <Rule Id="CA2231" Action="Warning" />
    <Rule Id="CA2232" Action="Warning" />
    <Rule Id="CA2233" Action="Warning" />
    <Rule Id="CA2234" Action="Warning" />
    <Rule Id="CA2235" Action="Warning" />
    <Rule Id="CA2236" Action="Warning" />
    <Rule Id="CA2237" Action="Warning" />
    <Rule Id="CA2238" Action="Warning" />
    <Rule Id="CA2239" Action="Warning" />
    <Rule Id="CA2240" Action="Warning" />
    <Rule Id="CA2241" Action="Warning" />
    <Rule Id="CA2242" Action="Warning" />
    <Rule Id="CA2243" Action="Warning" />
    <Rule Id="CA5122" Action="Warning" />
  </Rules>
  <Rules AnalyzerId="Microsoft.CodeAnalysis.CSharp" RuleNamespace="Microsoft.CodeAnalysis.CSharp">
    <Rule Id="AD0001" Action="Info" />
  </Rules>
  <Rules AnalyzerId="Microsoft.CodeQuality.Analyzers" RuleNamespace="Microsoft.CodeQuality.Analyzers">
    <Rule Id="CA1000" Action="None" />
  </Rules>
  <Rules AnalyzerId="RefactoringEssentials" RuleNamespace="RefactoringEssentials">
    <Rule Id="RECS0011" Action="Warning" />
    <Rule Id="RECS0018" Action="Hidden" />
    <Rule Id="RECS0022" Action="Info" />
    <Rule Id="RECS0025" Action="Info" />
    <Rule Id="RECS0033" Action="Hidden" />
    <Rule Id="RECS0059" Action="Warning" />
    <Rule Id="RECS0083" Action="Warning" />
    <Rule Id="RECS0091" Action="Hidden" />
    <Rule Id="RECS0092" Action="Warning" />
    <Rule Id="RECS0093" Action="Hidden" />
    <Rule Id="RECS0105" Action="Warning" />
    <Rule Id="RECS0106" Action="Hidden" />
    <Rule Id="RECS0122" Action="Warning" />
    <Rule Id="RECS0127" Action="Warning" />
    <Rule Id="RECS0130" Action="Hidden" />
    <Rule Id="RECS0145" Action="Error" />
    <Rule Id="RECS0152" Action="Warning" />
    <Rule Id="RECS0154" Action="Info" />
  </Rules>
  <Rules AnalyzerId="Roslynator.CSharp.Analyzers" RuleNamespace="Roslynator.CSharp.Analyzers">
    <Rule Id="RCS1001" Action="Error" />
    <Rule Id="RCS1018" Action="None" />
    <Rule Id="RCS1023" Action="None" />
    <Rule Id="RCS1024" Action="None" />
    <Rule Id="RCS1029" Action="None" />
    <Rule Id="RCS1095" Action="None" />
    <Rule Id="RCS1123" Action="None" />
  </Rules>
  <Rules AnalyzerId="SonarAnalyzer.CSharp" RuleNamespace="SonarAnalyzer.CSharp">
    <Rule Id="S100" Action="None" />
    <Rule Id="S101" Action="None" />
    <Rule Id="S108" Action="None" />
    <Rule Id="S110" Action="Info" />
    <Rule Id="S1121" Action="None" />
    <Rule Id="S1244" Action="None" />
    <Rule Id="S125" Action="None" />
    <Rule Id="S1449" Action="None" />
    <Rule Id="S1854" Action="None" />
    <Rule Id="S2360" Action="None" />
    <Rule Id="S2743" Action="None" />
    <Rule Id="S3776" Action="None" />
    <Rule Id="S3881" Action="None" />
  </Rules>
  <Rules AnalyzerId="StyleCop.Analyzers" RuleNamespace="StyleCop.Analyzers">
    <Rule Id="SA0001" Action="None" />
    <Rule Id="SA1008" Action="None" />
    <Rule Id="SA1009" Action="None" />
    <Rule Id="SA1028" Action="None" />
    <Rule Id="SA1101" Action="None" />
    <Rule Id="SA1108" Action="None" />
    <Rule Id="SA1117" Action="None" />
    <Rule Id="SA1118" Action="None" />
    <Rule Id="SA1122" Action="None" />
    <Rule Id="SA1200" Action="None" />
    <Rule Id="SA1201" Action="None" />
    <Rule Id="SA1202" Action="None" />
    <Rule Id="SA1203" Action="None" />
    <Rule Id="SA1204" Action="None" />
    <Rule Id="SA1205" Action="None" />
    <Rule Id="SA1208" Action="None" />
    <Rule Id="SA1210" Action="None" />
    <Rule Id="SA1214" Action="None" />
    <Rule Id="SA1311" Action="None" />
    <Rule Id="SA1400" Action="None" />
    <Rule Id="SA1401" Action="None" />
    <Rule Id="SA1407" Action="None" />
    <Rule Id="SA1408" Action="None" />
    <Rule Id="SA1413" Action="None" />
    <Rule Id="SA1513" Action="None" />
    <Rule Id="SA1600" Action="None" />
    <Rule Id="SA1602" Action="None" />
    <Rule Id="SA1606" Action="None" />
    <Rule Id="SA1614" Action="None" />
    <Rule Id="SA1616" Action="None" />
    <Rule Id="SA1633" Action="None" />
  </Rules>
  <Rules AnalyzerId="xunit.analyzers" RuleNamespace="xunit.analyzers">
    <Rule Id="xUnit1004" Action="Hidden" />
    <Rule Id="xUnit1005" Action="Error" />
    <Rule Id="xUnit1006" Action="Error" />
    <Rule Id="xUnit1008" Action="Error" />
    <Rule Id="xUnit1012" Action="Error" />
    <Rule Id="xUnit1013" Action="Error" />
    <Rule Id="xUnit1014" Action="Error" />
    <Rule Id="xUnit1024" Action="Hidden" />
    <Rule Id="xUnit2000" Action="Error" />
    <Rule Id="xUnit2001" Action="Error" />
    <Rule Id="xUnit2002" Action="Error" />
    <Rule Id="xUnit2003" Action="Error" />
    <Rule Id="xUnit2004" Action="Error" />
  </Rules>
</RuleSet>
Download .txt
gitextract_7ydao9jy/

├── .gitattributes
├── .gitignore
├── CONTRIBUTORS.md
├── IntervalTree/
│   ├── IIntervalTree.cs
│   ├── IntervalTree.cs
│   ├── IntervalTree.csproj
│   ├── IntervalTreeNode.cs
│   └── RangeValuePair.cs
├── IntervalTree.sln
├── IntervalTreeExamples/
│   ├── IntervalTreeExamples.csproj
│   └── Program.cs
├── IntervalTreeTests/
│   ├── ComparerTests.cs
│   ├── IntervalTreeTests.cs
│   ├── IntervalTreeTests.csproj
│   ├── MultipleComparerTests.cs
│   ├── ReadmeExampleTests.cs
│   ├── TreeOfDateTimeTests.cs
│   ├── TreeOfIntTests.cs
│   └── TreeSpecs.cs
├── LICENSE.txt
├── README.md
└── rangetree.ruleset
Download .txt
SYMBOL INDEX (78 symbols across 12 files)

FILE: IntervalTree/IIntervalTree.cs
  type IIntervalTree (line 12) | public interface IIntervalTree<TKey, TValue> : IEnumerable<RangeValuePai...
    method Query (line 27) | IEnumerable<TValue> Query(TKey value);
    method Query (line 32) | IEnumerable<TValue> Query(TKey from, TKey to);
    method Add (line 37) | void Add(TKey from, TKey to, TValue value);
    method Remove (line 42) | void Remove(TValue item);
    method Remove (line 47) | void Remove(IEnumerable<TValue> items);
    method Clear (line 52) | void Clear();

FILE: IntervalTree/IntervalTree.cs
  class IntervalTree (line 8) | public class IntervalTree<TKey, TValue> : IIntervalTree<TKey, TValue>
    method GetEnumerator (line 15) | IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
    method IntervalTree (line 46) | public IntervalTree() : this(Comparer<TKey>.Default) { }
    method IntervalTree (line 51) | public IntervalTree(IComparer<TKey> comparer)
    method Query (line 59) | public IEnumerable<TValue> Query(TKey value)
    method Query (line 67) | public IEnumerable<TValue> Query(TKey from, TKey to)
    method Add (line 75) | public void Add(TKey from, TKey to, TValue value)
    method Remove (line 84) | public void Remove(TValue value)
    method Remove (line 90) | public void Remove(IEnumerable<TValue> items)
    method Clear (line 96) | public void Clear()
    method GetEnumerator (line 103) | public IEnumerator<RangeValuePair<TKey, TValue>> GetEnumerator()
    method Rebuild (line 111) | private void Rebuild()

FILE: IntervalTree/IntervalTreeNode.cs
  class IntervalTreeNode (line 10) | internal class IntervalTreeNode<TKey, TValue> : IComparer<RangeValuePair...
    method IntervalTreeNode (line 23) | public IntervalTreeNode(IComparer<TKey> comparer)
    method IntervalTreeNode (line 38) | public IntervalTreeNode(IList<RangeValuePair<TKey, TValue>> items, ICo...
    method Compare (line 107) | int IComparer<RangeValuePair<TKey, TValue>>.Compare(RangeValuePair<TKe...
    method Query (line 120) | public IEnumerable<TValue> Query(TKey value)
    method Query (line 147) | public IEnumerable<TValue> Query(TKey from, TKey to)

FILE: IntervalTree/RangeValuePair.cs
  type RangeValuePair (line 11) | public readonly struct RangeValuePair<TKey, TValue> : IEquatable<RangeVa...
    method RangeValuePair (line 20) | public RangeValuePair(TKey from, TKey to, TValue value) : this()
    method ToString (line 33) | public override string ToString()
    method GetHashCode (line 38) | public override int GetHashCode()
    method Equals (line 50) | public bool Equals(RangeValuePair<TKey, TValue> other)
    method Equals (line 57) | public override bool Equals(object obj)

FILE: IntervalTreeExamples/Program.cs
  class Program (line 9) | class Program
    method Main (line 11) | static void Main(string[] args)
    method TreeExample1 (line 19) | static void TreeExample1()
    method TreeExample2 (line 39) | static void TreeExample2()
    method RandomTreeInsert (line 64) | static void RandomTreeInsert(IIntervalTree<int, string> tree, int limit)
    method PrintQueryResult (line 72) | static void PrintQueryResult(string queryTitle, IEnumerable<string> re...

FILE: IntervalTreeTests/ComparerTests.cs
  class ComparerTests (line 8) | [TestFixture]
    method AddingAnItem_FromIsLargerThanTo_ShouldThrowException (line 11) | [Test]
    method CreatingTreeWithNullComparer_AddingAnItem_ShouldNotThrowException (line 20) | [Test]

FILE: IntervalTreeTests/IntervalTreeTests.cs
  class IntervalTreeTests (line 6) | [TestFixture]
    method GettingMin_InnerItems (line 9) | [Test]
    method GettingMin_LeftRecurse (line 24) | [Test]
    method GettingMax_InnerItems (line 38) | [Test]
    method GettingMax_RightRecurse (line 53) | [Test]
    method GettingMin_Mixed (line 68) | [Test]
    method GettingMax_Mixed (line 83) | [Test]

FILE: IntervalTreeTests/MultipleComparerTests.cs
  class MultipleComparerTests (line 8) | [TestFixture]
    method CreateTwoTrees_ProvideDifferentComparers_ExpectBothToHaveTheComparersFromConstruction (line 11) | [Test]

FILE: IntervalTreeTests/ReadmeExampleTests.cs
  class ReadmeExampleTests (line 7) | [TestFixture]
    method Query_CreateTreeAndExecuteQuery_ExpectCorrectElementsToBeReturned (line 10) | [Test]

FILE: IntervalTreeTests/TreeOfDateTimeTests.cs
  class TreeOfDateTimeTests (line 8) | [TestFixture]
    method BuildEmptyIntervalTree (line 13) | [Test]
    method CreateEmptyIntervalTree (line 20) | [Test]
    method GetIntervalByExactEndTime (line 27) | [Test]
    method GetIntervalByExactStartTime (line 37) | [Test]
    method OverlapOnExactEndAndStart_AssertCount (line 53) | [Test]
    method TestSeparateIntervals (line 65) | [Test]
    method TwoIntersectingIntervals (line 77) | [Test]

FILE: IntervalTreeTests/TreeOfIntTests.cs
  class TreeOfIntTests (line 7) | [TestFixture]
    method BuildEmptyIntervalTree (line 10) | [Test]
    method CreateEmptyIntervalTree (line 17) | [Test]
    method TestSeparateIntervals (line 24) | [Test]
    method TwoIntersectingIntervals (line 36) | [Test]
    method QueryOutOfSyncTree_ExpectObsoleteResults (line 49) | [Test]

FILE: IntervalTreeTests/TreeSpecs.cs
  class If_the_user_searches_for_overlapping_entries_in_an_interval_tree (line 11) | [TestFixture]
    method TestEntries (line 14) | private static IEnumerable<Tuple<int, int>> TestEntries()
    method CorrectQuery_BuiltInOrder (line 48) | [Test]
    method CorrectQuery_BuiltInReverseOrder (line 58) | [Test]
    method CorrectQuery_BuiltRandomly (line 68) | [Test]
    method CreateTree (line 78) | private static IIntervalTree<int, string> CreateTree(IEnumerable<Tuple...
  class Spec (line 94) | [DebuggerStepThrough]
    method SetUp (line 98) | [DebuggerStepThrough]
    method TearDown (line 106) | [DebuggerStepThrough]
    method EstablishContext (line 116) | [DebuggerStepThrough]
    method BecauseOf (line 122) | [DebuggerStepThrough]
    method Cleanup (line 128) | [DebuggerStepThrough]
    method Invoking (line 136) | protected Action Invoking(Action func)
Condensed preview — 22 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (68K chars).
[
  {
    "path": ".gitattributes",
    "chars": 2518,
    "preview": "###############################################################################\n# Set default behavior to automatically "
  },
  {
    "path": ".gitignore",
    "chars": 3156,
    "preview": "## Ignore Visual Studio temporary files, build results, and\n## files generated by popular Visual Studio add-ons.\n\n# User"
  },
  {
    "path": "CONTRIBUTORS.md",
    "chars": 164,
    "preview": "Special thanks to the contributors\n\n- [Steve Hansen](https://github.com/beefo)\n- [Eric Domke](https://github.com/erdomke"
  },
  {
    "path": "IntervalTree/IIntervalTree.cs",
    "chars": 1827,
    "preview": "using System.Collections.Generic;\n\nnamespace IntervalTree\n{\n    /// <summary>\n    /// The standard interval tree implem"
  },
  {
    "path": "IntervalTree/IntervalTree.cs",
    "chars": 3249,
    "preview": "using System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Linq;\n\nnamespace IntervalTree\n{\n"
  },
  {
    "path": "IntervalTree/IntervalTree.csproj",
    "chars": 2692,
    "preview": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n  <PropertyGroup>\n    <TargetFrameworks>netstandard1.2;netstandard2.0;net45</TargetF"
  },
  {
    "path": "IntervalTree/IntervalTreeNode.cs",
    "chars": 6616,
    "preview": "using System.Collections.Generic;\n\nnamespace IntervalTree\n{\n    /// <summary>\n    ///     A node of the range tree. Giv"
  },
  {
    "path": "IntervalTree/RangeValuePair.cs",
    "chars": 2407,
    "preview": "using System;\nusing System.Collections.Generic;\n\nnamespace IntervalTree\n{\n    /// <summary>\n    /// Represents a range "
  },
  {
    "path": "IntervalTree.sln",
    "chars": 2121,
    "preview": "\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio Version 16\nVisualStudioVersion = 16.0.3001"
  },
  {
    "path": "IntervalTreeExamples/IntervalTreeExamples.csproj",
    "chars": 1083,
    "preview": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n  <PropertyGroup>\n    <TargetFramework>netstandard1.6</TargetFramework>\n  </Property"
  },
  {
    "path": "IntervalTreeExamples/Program.cs",
    "chars": 2222,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\nusing IntervalTree;\n\nnames"
  },
  {
    "path": "IntervalTreeTests/ComparerTests.cs",
    "chars": 786,
    "preview": "using System;\nusing System.Collections.Generic;\nusing IntervalTree;\nusing NUnit.Framework;\n\nnamespace IntervalTreeTests"
  },
  {
    "path": "IntervalTreeTests/IntervalTreeTests.cs",
    "chars": 2111,
    "preview": "using NUnit.Framework;\nusing IntervalTree;\n\nnamespace IntervalTreeTests\n{\n    [TestFixture]\n    public class IntervalTr"
  },
  {
    "path": "IntervalTreeTests/IntervalTreeTests.csproj",
    "chars": 1533,
    "preview": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n  <PropertyGroup>    \n    <TargetFramework>netcoreapp2.1</TargetFramework>\n  </Prope"
  },
  {
    "path": "IntervalTreeTests/MultipleComparerTests.cs",
    "chars": 1098,
    "preview": "using System;\nusing System.Linq;\nusing NUnit.Framework;\nusing IntervalTree;\n\nnamespace IntervalTreeTests\n{\n    [TestFix"
  },
  {
    "path": "IntervalTreeTests/ReadmeExampleTests.cs",
    "chars": 1272,
    "preview": "using System.Linq;\nusing NUnit.Framework;\nusing IntervalTree;\n\nnamespace IntervalTreeTests\n{\n    [TestFixture]\n    publ"
  },
  {
    "path": "IntervalTreeTests/TreeOfDateTimeTests.cs",
    "chars": 2796,
    "preview": "using System;\nusing System.Linq;\nusing NUnit.Framework;\nusing IntervalTree;\n\nnamespace IntervalTreeTests\n{\n    [TestFix"
  },
  {
    "path": "IntervalTreeTests/TreeOfIntTests.cs",
    "chars": 1711,
    "preview": "using System.Linq;\nusing NUnit.Framework;\nusing IntervalTree;\n\nnamespace IntervalTreeTests\n{\n    [TestFixture]\n    inte"
  },
  {
    "path": "IntervalTreeTests/TreeSpecs.cs",
    "chars": 4699,
    "preview": "using System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\n"
  },
  {
    "path": "LICENSE.txt",
    "chars": 1161,
    "preview": "If not noted otherwise in the file header, the project uses the MIT license.\n\nCopyright (c) 2020, Matthias Buchetics and"
  },
  {
    "path": "README.md",
    "chars": 3423,
    "preview": "# IntervalTree #\n\n[![Build status](https://ci.appveyor.com/api/projects/status/t8xvh5oquuvk17ks?svg=true)](https://ci.ap"
  },
  {
    "path": "rangetree.ruleset",
    "chars": 14461,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RuleSet Name=\"RangeTree\" Description=\"These rules focus on the most critical pr"
  }
]

About this extraction

This page contains the full source code of the mbuchetics/RangeTree GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 22 files (61.6 KB), approximately 17.0k tokens, and a symbol index with 78 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!