Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

385 lines (346 sloc) 12.368 kB
/* Copyright 2010-2012 10gen Inc.
*
* Licensed 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 System;
using System.Collections.Generic;
using MongoDB.Bson;
namespace MongoDB.Driver
{
/// <summary>
/// Server connection mode.
/// </summary>
[Serializable]
public enum ConnectionMode
{
/// <summary>
/// Connect directly to a server.
/// </summary>
Direct,
/// <summary>
/// Connect to a replica set.
/// </summary>
ReplicaSet
}
/// <summary>
/// Represents an immutable URL style connection string. See also MongoUrlBuilder.
/// </summary>
[Serializable]
public class MongoUrl : IEquatable<MongoUrl>
{
// private static fields
private static object __staticLock = new object();
private static Dictionary<string, MongoUrl> __cache = new Dictionary<string, MongoUrl>();
// private fields
private MongoServerSettings _serverSettings;
private double _waitQueueMultiple;
private int _waitQueueSize;
private string _databaseName;
private string _url;
// constructors
/// <summary>
/// Creates a new instance of MongoUrl.
/// </summary>
/// <param name="url">The URL containing the settings.</param>
public MongoUrl(string url)
{
var builder = new MongoUrlBuilder(url); // parses url
_serverSettings = builder.ToServerSettings().FrozenCopy();
_waitQueueMultiple = builder.WaitQueueMultiple;
_waitQueueSize = builder.WaitQueueSize;
_databaseName = builder.DatabaseName;
_url = builder.ToString(); // keep canonical form
}
// public properties
/// <summary>
/// Gets the actual wait queue size (either WaitQueueSize or WaitQueueMultiple x MaxConnectionPoolSize).
/// </summary>
public int ComputedWaitQueueSize
{
get
{
if (_waitQueueMultiple == 0.0)
{
return _waitQueueSize;
}
else
{
return (int)(_waitQueueMultiple * _serverSettings.MaxConnectionPoolSize);
}
}
}
/// <summary>
/// Gets the connection mode.
/// </summary>
public ConnectionMode ConnectionMode
{
get { return _serverSettings.ConnectionMode; }
}
/// <summary>
/// Gets the connect timeout.
/// </summary>
public TimeSpan ConnectTimeout
{
get { return _serverSettings.ConnectTimeout; }
}
/// <summary>
/// Gets the optional database name.
/// </summary>
public string DatabaseName
{
get { return _databaseName; }
}
/// <summary>
/// Gets the default credentials.
/// </summary>
public MongoCredentials DefaultCredentials
{
get { return _serverSettings.DefaultCredentials; }
}
/// <summary>
/// Gets the representation to use for Guids.
/// </summary>
public GuidRepresentation GuidRepresentation
{
get { return _serverSettings.GuidRepresentation; }
}
/// <summary>
/// Gets whether to use IPv6.
/// </summary>
public bool IPv6
{
get { return _serverSettings.IPv6; }
}
/// <summary>
/// Gets the max connection idle time.
/// </summary>
public TimeSpan MaxConnectionIdleTime
{
get { return _serverSettings.MaxConnectionIdleTime; }
}
/// <summary>
/// Gets the max connection life time.
/// </summary>
public TimeSpan MaxConnectionLifeTime
{
get { return _serverSettings.MaxConnectionLifeTime; }
}
/// <summary>
/// Gets the max connection pool size.
/// </summary>
public int MaxConnectionPoolSize
{
get { return _serverSettings.MaxConnectionPoolSize; }
}
/// <summary>
/// Gets the min connection pool size.
/// </summary>
public int MinConnectionPoolSize
{
get { return _serverSettings.MinConnectionPoolSize; }
}
/// <summary>
/// Gets the name of the replica set.
/// </summary>
public string ReplicaSetName
{
get { return _serverSettings.ReplicaSetName; }
}
/// <summary>
/// Gets the SafeMode to use.
/// </summary>
public SafeMode SafeMode
{
get { return _serverSettings.SafeMode; }
}
/// <summary>
/// Gets the address of the server (see also Servers if using more than one address).
/// </summary>
public MongoServerAddress Server
{
get { return _serverSettings.Server; }
}
/// <summary>
/// Gets the list of server addresses (see also Server if using only one address).
/// </summary>
public IEnumerable<MongoServerAddress> Servers
{
get { return _serverSettings.Servers; }
}
/// <summary>
/// Gets whether queries should be sent to secondary servers.
/// </summary>
public bool SlaveOk
{
get { return _serverSettings.SlaveOk; }
}
/// <summary>
/// Gets the socket timeout.
/// </summary>
public TimeSpan SocketTimeout
{
get { return _serverSettings.SocketTimeout; }
}
/// <summary>
/// Gets the URL (in canonical form).
/// </summary>
public string Url
{
get { return _url; }
}
/// <summary>
/// Gets the wait queue multiple (the actual wait queue size will be WaitQueueMultiple x MaxConnectionPoolSize).
/// </summary>
public double WaitQueueMultiple
{
get { return _waitQueueMultiple; }
}
/// <summary>
/// Gets the wait queue size.
/// </summary>
public int WaitQueueSize
{
get { return _waitQueueSize; }
}
/// <summary>
/// Gets the wait queue timeout.
/// </summary>
public TimeSpan WaitQueueTimeout
{
get { return _serverSettings.WaitQueueTimeout; }
}
// public operators
/// <summary>
/// Compares two MongoUrls.
/// </summary>
/// <param name="lhs">The first URL.</param>
/// <param name="rhs">The other URL.</param>
/// <returns>True if the two URLs are equal (or both null).</returns>
public static bool operator ==(MongoUrl lhs, MongoUrl rhs)
{
return object.Equals(lhs, rhs);
}
/// <summary>
/// Compares two MongoUrls.
/// </summary>
/// <param name="lhs">The first URL.</param>
/// <param name="rhs">The other URL.</param>
/// <returns>True if the two URLs are not equal (or one is null and the other is not).</returns>
public static bool operator !=(MongoUrl lhs, MongoUrl rhs)
{
return !(lhs == rhs);
}
// public static methods
/// <summary>
/// Clears the URL cache. When a URL is parsed it is stored in the cache so that it doesn't have to be
/// parsed again. There is rarely a need to call this method.
/// </summary>
public static void ClearCache()
{
// Replace cache with new empty one. GC will remove old cache when not referenced.
lock(__staticLock)
{
__cache = new Dictionary<string, MongoUrl>();
}
}
/// <summary>
/// Creates an instance of MongoUrl (might be an existing existence if the same URL has been used before).
/// </summary>
/// <param name="url">The URL containing the settings.</param>
/// <returns>An instance of MongoUrl.</returns>
public static MongoUrl Create(string url)
{
// cache previously seen urls to avoid repeated parsing
MongoUrl mongoUrl;
// get ref to current dictionary instance.
var cacheRef = __cache;
if (!cacheRef.TryGetValue(url, out mongoUrl))
{
lock (__staticLock)
{
// re-grab the current cache ref. We got lock, but another thread may have modified before we entered lock.
cacheRef = __cache;
if (!cacheRef.TryGetValue(url, out mongoUrl))
{
mongoUrl = new MongoUrl(url);
var canonicalUrl = mongoUrl.ToString();
if (canonicalUrl != url)
{
if (cacheRef.ContainsKey(canonicalUrl))
{
mongoUrl = cacheRef[canonicalUrl]; // use existing MongoUrl
}
else
{
cacheRef[canonicalUrl] = mongoUrl; // cache under canonicalUrl also
}
}
// copy old dictionary values to new one. Can't guarantee concurrent write while unlocked reader may be accessing cachRef
Dictionary<string, MongoUrl> updatedCache = new Dictionary<string, MongoUrl>(cacheRef.Count+1);
updatedCache[url] = mongoUrl;
foreach (var entry in cacheRef)
{
updatedCache[entry.Key] = entry.Value;
}
__cache = updatedCache;
}
}
}
return mongoUrl;
}
// public methods
/// <summary>
/// Compares two MongoUrls.
/// </summary>
/// <param name="rhs">The other URL.</param>
/// <returns>True if the two URLs are equal.</returns>
public bool Equals(MongoUrl rhs)
{
if (object.ReferenceEquals(rhs, null) || GetType() != rhs.GetType()) { return false; }
return _url == rhs._url; // this works because URL is in canonical form
}
/// <summary>
/// Compares two MongoUrls.
/// </summary>
/// <param name="obj">The other URL.</param>
/// <returns>True if the two URLs are equal.</returns>
public override bool Equals(object obj)
{
return Equals(obj as MongoUrl); // works even if obj is null or of a different type
}
/// <summary>
/// Gets the hash code.
/// </summary>
/// <returns>The hash code.</returns>
public override int GetHashCode()
{
return _url.GetHashCode(); // this works because URL is in canonical form
}
/// <summary>
/// Creates a new instance of MongoServerSettings based on the settings in this MongoUrlBuilder.
/// </summary>
/// <returns>A new instance of MongoServerSettings.</returns>
public MongoServerSettings ToServerSettings()
{
return _serverSettings;
}
/// <summary>
/// Returns the canonical URL based on the settings in this MongoUrlBuilder.
/// </summary>
/// <returns>The canonical URL.</returns>
public override string ToString()
{
return _url;
}
}
}
Jump to Line
Something went wrong with that request. Please try again.