<commit_before>﻿/*
 *  Licensed to SharpSoftware under one or more contributor
 *  license agreements. See the NOTICE file distributed with this work for 
 *  additional information regarding copyright ownership.
 * 
 *  SharpSoftware licenses this file to you under the Apache License, 
 *  Version 2.0 (the "License"); you may not use this file except in 
 *  compliance with the License. You may obtain a copy of the License at
 * 
 *       http://www.apache.org/licenses/LICENSE-2.0
 * 
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

using Itinero.Algorithms.Default;
using Itinero.Algorithms.Routes;
using Itinero.Algorithms.Search;
using Itinero.Exceptions;
using Itinero.Graphs.Geometric;
using Itinero.Data.Network;
using Itinero.Profiles;
using System;
using System.Collections.Generic;
using Itinero.Data.Contracted;
using Itinero.Algorithms;
using Itinero.Algorithms.Weights;
using Itinero.Data;

namespace Itinero
{
    /// <summary>
    /// A router implementation encapsulating basic routing functionalities.
    /// </summary>
    public sealed class Router : RouterBase
    {
        private readonly RouterDb _db;

        /// <summary>
        /// Creates a new router.
        /// </summary>
        public Router(RouterDb db)
        {
            _db = db;

            this.ProfileFactorAndSpeedCache = new ProfileFactorAndSpeedCache(db);
            this.VerifyAllStoppable = false;
        }

        /// <summary>
        /// Gets or sets the delegate to create a custom resolver.
        /// </summary>
        public IResolveExtensions.CreateResolver CreateCustomResolver { get; set; }

        /// <summary>
        /// Gets or sets the custom route builder.
        /// </summary>
        public IRouteBuilder CustomRouteBuilder { get; set; }

        /// <summary>
        /// Gets the db.
        /// </summary>
        public override sealed RouterDb Db
        {
            get
            {
                return _db;
            }
        }

        /// <summary>
        /// Searches for the closest point on the routing network that's routable for the given profiles.
        /// </summary>
        /// <returns></returns>
        public sealed override Result<RouterPoint> TryResolve(IProfileInstance[] profileInstances, float latitude, float longitude,
            Func<RoutingEdge, bool> isBetter, float maxSearchDistance = Constants.SearchDistanceInMeter, ResolveSettings settings = null)
        {
            if (settings == null)
            {
                settings = new ResolveSettings();
            }

            try
            {
                if (!_db.SupportsAll(profileInstances))
                {
                    return new Result<RouterPoint>("Not all routing profiles are supported.", (message) =>
                    {
                        return new Exceptions.ResolveFailedException(message);
                    });
                }

                IResolver resolver = null;

                // get is acceptable.
                var isAcceptable = this.GetIsAcceptable(profileInstances);

                // enhance is acceptable with islands if needed and if island are there.
                if (settings.MinIslandSize > 0)
                {
                    MetaCollection<ushort>[] islands = null;
                    for (var p = 0; p < profileInstances.Length; p++)
                    {
                        MetaCollection<ushort> il;
                        if (this.Db.VertexData.TryGet("islands_" + profileInstances[p].Profile.FullName, out il))
                        {
                            if (islands == null)
                            {
                                islands = new MetaCollection<ushort>[profileInstances.Length];
                            }
                            islands[p] = il;
                        }
                    }

                    if (islands != null)
                    { // override default is acceptable and also check islands.
                        var oldIsAcceptable = isAcceptable;
                        isAcceptable = new Func<GeometricEdge, bool>(edge =>
                        {
                            if (!oldIsAcceptable(edge))
                            { // fail fast.
                                return false;
                            }

                            foreach (var il in islands)
                            {
                                if (il == null)<commit_msg>VertexMeta can be null.<commit_after>﻿/*
 *  Licensed to SharpSoftware under one or more contributor
 *  license agreements. See the NOTICE file distributed with this work for 
 *  additional information regarding copyright ownership.
 * 
 *  SharpSoftware licenses this file to you under the Apache License, 
 *  Version 2.0 (the "License"); you may not use this file except in 
 *  compliance with the License. You may obtain a copy of the License at
 * 
 *       http://www.apache.org/licenses/LICENSE-2.0
 * 
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

using Itinero.Algorithms.Default;
using Itinero.Algorithms.Routes;
using Itinero.Algorithms.Search;
using Itinero.Exceptions;
using Itinero.Graphs.Geometric;
using Itinero.Data.Network;
using Itinero.Profiles;
using System;
using System.Collections.Generic;
using Itinero.Data.Contracted;
using Itinero.Algorithms;
using Itinero.Algorithms.Weights;
using Itinero.Data;

namespace Itinero
{
    /// <summary>
    /// A router implementation encapsulating basic routing functionalities.
    /// </summary>
    public sealed class Router : RouterBase
    {
        private readonly RouterDb _db;

        /// <summary>
        /// Creates a new router.
        /// </summary>
        public Router(RouterDb db)
        {
            _db = db;

            this.ProfileFactorAndSpeedCache = new ProfileFactorAndSpeedCache(db);
            this.VerifyAllStoppable = false;
        }

        /// <summary>
        /// Gets or sets the delegate to create a custom resolver.
        /// </summary>
        public IResolveExtensions.CreateResolver CreateCustomResolver { get; set; }

        /// <summary>
        /// Gets or sets the custom route builder.
        /// </summary>
        public IRouteBuilder CustomRouteBuilder { get; set; }

        /// <summary>
        /// Gets the db.
        /// </summary>
        public override sealed RouterDb Db
        {
            get
            {
                return _db;
            }
        }

        /// <summary>
        /// Searches for the closest point on the routing network that's routable for the given profiles.
        /// </summary>
        /// <returns></returns>
        public sealed override Result<RouterPoint> TryResolve(IProfileInstance[] profileInstances, float latitude, float longitude,
            Func<RoutingEdge, bool> isBetter, float maxSearchDistance = Constants.SearchDistanceInMeter, ResolveSettings settings = null)
        {
            if (settings == null)
            {
                settings = new ResolveSettings();
            }

            try
            {
                if (!_db.SupportsAll(profileInstances))
                {
                    return new Result<RouterPoint>("Not all routing profiles are supported.", (message) =>
                    {
                        return new Exceptions.ResolveFailedException(message);
                    });
                }

                IResolver resolver = null;

                // get is acceptable.
                var isAcceptable = this.GetIsAcceptable(profileInstances);

                // enhance is acceptable with islands if needed and if island are there.
                if (settings.MinIslandSize > 0)
                {
                    MetaCollection<ushort>[] islands = null;
                    for (var p = 0; p < profileInstances.Length; p++)
                    {
                        MetaCollection<ushort> il;
                        if (this.Db.VertexData != null &&
                            this.Db.VertexData.TryGet("islands_" + profileInstances[p].Profile.FullName, out il))
                        {
                            if (islands == null)
                            {
                                islands = new MetaCollection<ushort>[profileInstances.Length];
                            }
                            islands[p] = il;
                        }
                    }

                    if (islands != null)
                    { // override default is acceptable and also check islands.
                        var oldIsAcceptable = isAcceptable;
                        isAcceptable = new Func<GeometricEdge, bool>(edge =>
                        {
                            if (!oldIsAcceptable(edge))
                            { // fail fast.
                                return false;
                            }

                            foreach (var il in islands)
                            {
                                if (il == null)
{'fraction_non_alphanumeric': 0.07945291292545417, 'fraction_numerical': 0.001252871163082063, 'mean_word_length': 1.4822492873801503, 'pattern_counts': {'":': 0, '<': 47, '<?xml version=': 0, '>': 51, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2810621', 'n_tokens_mistral': 2321, 'n_tokens_neox': 2203, 'n_words': 710}