add from giga-device, new branch added
This commit is contained in:
@@ -0,0 +1,206 @@
|
||||
//-----------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------
|
||||
// file="BidirectionalDictionary.cs"
|
||||
// Project: StgSharp
|
||||
// AuthorGroup: Nitload Space
|
||||
// Copyright (c) Nitload Space. All rights reserved.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//-----------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
|
||||
namespace StgSharp.Commom.Collections
|
||||
{
|
||||
public sealed class BidirectionalDictionary<TFirst, TSecond> : IBidirectionalDictionary<TFirst, TSecond>
|
||||
{
|
||||
|
||||
private readonly Dictionary<TFirst, TSecond> _forward;
|
||||
private readonly Dictionary<TSecond, TFirst> _reverse;
|
||||
|
||||
public BidirectionalDictionary()
|
||||
{
|
||||
_forward = new Dictionary<TFirst, TSecond>();
|
||||
_reverse = new Dictionary<TSecond, TFirst>();
|
||||
}
|
||||
|
||||
public TFirst this[ TSecond key ]
|
||||
{
|
||||
get
|
||||
{
|
||||
if( _reverse.TryGetValue( key, out TFirst value ) ) {
|
||||
return value;
|
||||
}
|
||||
throw new ArgumentException( $"Cannot find key {key!.ToString()} in dictionary." );
|
||||
}
|
||||
set
|
||||
{
|
||||
if( _reverse.TryGetValue( key, out TFirst origin ) )
|
||||
{
|
||||
_reverse[ key ] = value;
|
||||
_forward.Remove( origin );
|
||||
} else
|
||||
{
|
||||
_reverse.Add( key, value );
|
||||
}
|
||||
_forward.Add( value, key );
|
||||
}
|
||||
}
|
||||
|
||||
public TSecond this[ TFirst key ]
|
||||
{
|
||||
get
|
||||
{
|
||||
if( _forward.TryGetValue( key, out TSecond value ) ) {
|
||||
return value;
|
||||
}
|
||||
throw new ArgumentException( $"Cannot find key {key!.ToString()} in dictionary." );
|
||||
}
|
||||
set
|
||||
{
|
||||
if( _forward.TryGetValue( key, out TSecond origin ) )
|
||||
{
|
||||
_forward[ key ] = value;
|
||||
_reverse.Remove( origin );
|
||||
} else
|
||||
{
|
||||
_forward.Add( key, value );
|
||||
}
|
||||
_reverse.Add( value, key );
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsReadOnly => false;
|
||||
|
||||
public ICollection<TFirst> FirstIndex => _forward.Keys;
|
||||
|
||||
public ICollection<TSecond> SecondIndex => _reverse.Keys;
|
||||
|
||||
public int Count => _forward.Count;
|
||||
|
||||
public IReadOnlyDictionary<TFirst, TSecond> Forward => new ReadOnlyDictionary<TFirst, TSecond>(
|
||||
_forward );
|
||||
|
||||
public IReadOnlyDictionary<TSecond, TFirst> Reverse => new ReadOnlyDictionary<TSecond, TFirst>(
|
||||
_reverse );
|
||||
|
||||
public void Add( KeyValuePair<TFirst, TSecond> item )
|
||||
{
|
||||
if( _forward.ContainsKey( item.Key ) || _reverse.ContainsKey( item.Value ) ) {
|
||||
throw new ArgumentException( "Duplicate key or value." );
|
||||
}
|
||||
_forward.Add( item.Key, item.Value );
|
||||
_reverse.Add( item.Value, item.Key );
|
||||
}
|
||||
|
||||
public void Add( TFirst key, TSecond value )
|
||||
{
|
||||
if( _forward.ContainsKey( key ) || _reverse.ContainsKey( value ) ) {
|
||||
throw new ArgumentException( "Duplicate key or value." );
|
||||
}
|
||||
_forward.Add( key, value );
|
||||
_reverse.Add( value, key );
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
_forward.Clear();
|
||||
_reverse.Clear();
|
||||
}
|
||||
|
||||
public bool Contains( KeyValuePair<TFirst, TSecond> item )
|
||||
{
|
||||
return _forward.Contains( item ) &&
|
||||
_reverse.TryGetValue( item.Value, out TFirst var ) &&
|
||||
var!.Equals( item.Key );
|
||||
}
|
||||
|
||||
public bool Contains( TSecond key )
|
||||
{
|
||||
return _reverse.ContainsKey( key );
|
||||
}
|
||||
|
||||
public bool Contains( TFirst key )
|
||||
{
|
||||
return _forward.ContainsKey( key );
|
||||
}
|
||||
|
||||
public void CopyTo( KeyValuePair<TFirst, TSecond>[] array, int arrayIndex )
|
||||
{
|
||||
if( array == null ) {
|
||||
throw new ArgumentNullException( nameof( array ) );
|
||||
}
|
||||
if( arrayIndex < 0 || arrayIndex > array.Length ) {
|
||||
throw new ArgumentOutOfRangeException( nameof( arrayIndex ) );
|
||||
}
|
||||
if( array.Length - arrayIndex < _forward.Count ) {
|
||||
throw new ArgumentException( "The array is too small to copy the elements." );
|
||||
}
|
||||
|
||||
foreach( KeyValuePair<TFirst, TSecond> pair in _forward ) {
|
||||
array[ arrayIndex++ ] = pair;
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerator<KeyValuePair<TFirst, TSecond>> GetEnumerator()
|
||||
{
|
||||
foreach( KeyValuePair<TFirst, TSecond> pair in _forward ) {
|
||||
yield return pair;
|
||||
}
|
||||
}
|
||||
|
||||
public bool Remove( TFirst key )
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool Remove( KeyValuePair<TFirst, TSecond> item )
|
||||
{
|
||||
if( _forward.Remove( item.Key ) ) {
|
||||
return _reverse.Remove( item.Value );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool TryGetValue( TFirst key, out TSecond value )
|
||||
{
|
||||
return _forward.TryGetValue( key, out value );
|
||||
}
|
||||
|
||||
public bool TryGetValue( TSecond key, out TFirst value )
|
||||
{
|
||||
return _reverse.TryGetValue( key, out value );
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,191 @@
|
||||
//-----------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------
|
||||
// file="CapacityFixedList.cs"
|
||||
// Project: StgSharp
|
||||
// AuthorGroup: Nitload Space
|
||||
// Copyright (c) Nitload Space. All rights reserved.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//-----------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
|
||||
namespace StgSharp.Commom.Collections
|
||||
{
|
||||
public static class CapacityFixedListBuilder
|
||||
{
|
||||
|
||||
internal static CapacityFixedList<T> Create<T>( ReadOnlySpan<T> values )
|
||||
{
|
||||
return new CapacityFixedList<T>( values );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[CollectionBuilder(
|
||||
typeof( CapacityFixedListBuilder ),
|
||||
nameof( CapacityFixedListBuilder.Create ) )]
|
||||
public class CapacityFixedList<T> : IList<T>
|
||||
{
|
||||
|
||||
private T[] _values;
|
||||
private int capacity, _index;
|
||||
|
||||
public CapacityFixedList( int size )
|
||||
{
|
||||
_values = new T[size];
|
||||
}
|
||||
|
||||
public CapacityFixedList( ReadOnlySpan<T> values )
|
||||
{
|
||||
_values = values.ToArray();
|
||||
}
|
||||
|
||||
public T this[ int index ]
|
||||
{
|
||||
get => index < _index ?
|
||||
_values[ index ] : throw new ArgumentOutOfRangeException( nameof( index ) );
|
||||
set
|
||||
{
|
||||
if( index < _index )
|
||||
{
|
||||
_values[ index ] = value;
|
||||
} else
|
||||
{
|
||||
throw new ArgumentOutOfRangeException( nameof( index ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsReadOnly => false;
|
||||
|
||||
public int Count => _index + 1;
|
||||
|
||||
public void Add( T item )
|
||||
{
|
||||
if( _index < capacity - 1 )
|
||||
{
|
||||
_index++;
|
||||
this[ _index ] = item;
|
||||
}
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
_values = new T[capacity];
|
||||
_index = 0;
|
||||
}
|
||||
|
||||
public bool Contains( T item )
|
||||
{
|
||||
for( int i = 0; i <= _index; i++ )
|
||||
{
|
||||
if( item.Equals( _values[ i ] ) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void CopyTo( T[] array, int arrayIndex )
|
||||
{
|
||||
_values.CopyTo( array, arrayIndex );
|
||||
}
|
||||
|
||||
public IEnumerator<T> GetEnumerator()
|
||||
{
|
||||
for( int i = 0; i <= _index; i++ ) {
|
||||
yield return _values[ i ];
|
||||
}
|
||||
}
|
||||
|
||||
public int IndexOf( T item )
|
||||
{
|
||||
T v;
|
||||
for( int i = 0; i <= _index; i++ )
|
||||
{
|
||||
if( ( v = _values[ i ] ) != null && v.Equals( item ) ) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public bool Remove( T item )
|
||||
{
|
||||
T v;
|
||||
for( int i = 0; i <= _index; i++ )
|
||||
{
|
||||
if( ( v = _values[ i ] ) != null && v.Equals( item ) )
|
||||
{
|
||||
_values[ i ] = _values[ _index ];
|
||||
_index--;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void RemoveAll( Predicate<T> predicate )
|
||||
{
|
||||
for( int i = _index; i > 0; i-- )
|
||||
{
|
||||
if( predicate( _values[ i ] ) )
|
||||
{
|
||||
_values[ i ] = _values[ _index ];
|
||||
_index--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveAt( int index )
|
||||
{
|
||||
if( index <= _index )
|
||||
{
|
||||
_values[ index ] = _values[ _index ];
|
||||
_index--;
|
||||
}
|
||||
}
|
||||
|
||||
public void Resize( int newSize )
|
||||
{
|
||||
Array.Resize( ref _values, newSize );
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
yield return GetEnumerator();
|
||||
}
|
||||
|
||||
void IList<T>.Insert( int index, T item )
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
}//------------------------------------- End of Class ------------------------------------------
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
//-----------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------
|
||||
// file="IBidrirectionalDictionary.cs"
|
||||
// Project: StgSharp
|
||||
// AuthorGroup: Nitload Space
|
||||
// Copyright (c) Nitload Space. All rights reserved.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//-----------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace StgSharp.Commom.Collections
|
||||
{
|
||||
public interface IBidirectionalDictionary<TFirst, TSecond> : IDictionary<TFirst, TSecond>
|
||||
{
|
||||
|
||||
public TFirst this[ TSecond key ] { get; set; }
|
||||
|
||||
public ICollection<TFirst> FirstIndex { get; }
|
||||
|
||||
public ICollection<TSecond> SecondIndex { get; }
|
||||
|
||||
public IReadOnlyDictionary<TFirst, TSecond> Forward { get; }
|
||||
|
||||
public IReadOnlyDictionary<TSecond, TFirst> Reverse { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the <see cref="IBidirectionalDictionary{TFirst, TSecond}" />
|
||||
/// contains the specified key.
|
||||
/// </summary>
|
||||
/// <param _label="key">
|
||||
/// The value to locate in the <see cref="IBidirectionalDictionary{TFirst, TSecond}" />.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// true if the <see cref="IBidirectionalDictionary{TFirst, TSecond}" /> contains an
|
||||
/// element with the specified key; otherwise, false.
|
||||
/// </returns>
|
||||
public bool Contains( TSecond key );
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the <see cref="IBidirectionalDictionary{TFirst, TSecond}" />
|
||||
/// contains the specified key.
|
||||
/// </summary>
|
||||
/// <param _label="key">
|
||||
/// The value to locate in the <see cref="IBidirectionalDictionary{TFirst, TSecond}" />.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// true if the <see cref="IBidirectionalDictionary{TFirst, TSecond}" /> contains an
|
||||
/// element with the specified key; otherwise, false.
|
||||
/// </returns>
|
||||
public bool Contains( TFirst key );
|
||||
|
||||
public bool TryGetValue( TSecond key, out TFirst value );
|
||||
|
||||
#pragma warning disable CA1033
|
||||
ICollection<TFirst> IDictionary<TFirst, TSecond>.Keys => FirstIndex;
|
||||
|
||||
ICollection<TSecond> IDictionary<TFirst, TSecond>.Values => SecondIndex;
|
||||
|
||||
bool IDictionary<TFirst, TSecond>.ContainsKey( TFirst key ) => Contains( key );
|
||||
#pragma warning restore CA1033
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
//-----------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------
|
||||
// file="IHashMultiplexer.cs"
|
||||
// Project: StgSharp
|
||||
// AuthorGroup: Nitload Space
|
||||
// Copyright (c) Nitload Space. All rights reserved.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//-----------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace StgSharp.Collections
|
||||
{
|
||||
public interface IHashMultiplexer<T> : IEqualityComparer<T>
|
||||
{
|
||||
|
||||
int RemainedMultiplexCount { get; set; }
|
||||
|
||||
void CacheHash( T obj, int count );
|
||||
|
||||
void ExtendCache( int count );
|
||||
|
||||
int ForceComputeHash( T count );
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
//-----------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------
|
||||
// file="ListSegment.cs"
|
||||
// Project: StgSharp
|
||||
// AuthorGroup: Nitload Space
|
||||
// Copyright (c) Nitload Space. All rights reserved.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//-----------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace StgSharp.Collections
|
||||
{
|
||||
/// <summary>
|
||||
/// Part of a collection. This contains a direct reference to _origin collection, so all
|
||||
/// change to _origin collection will be reflected in this object.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">
|
||||
///
|
||||
/// </typeparam>
|
||||
public struct ListSegment<T> : ICollection<T>
|
||||
{
|
||||
|
||||
private int _begin;
|
||||
private int _length;
|
||||
private List<T> _collection;
|
||||
|
||||
public ListSegment( List<T> collection, int begin, int length )
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull( collection );
|
||||
ArgumentOutOfRangeException.ThrowIfLessThan( begin, 0 );
|
||||
ArgumentOutOfRangeException.ThrowIfLessThan( length, 0 );
|
||||
ArgumentOutOfRangeException.ThrowIfLessThan( begin + length, collection.Count );
|
||||
_collection = collection;
|
||||
_begin = begin;
|
||||
_length = length;
|
||||
}
|
||||
|
||||
public T this[ int indexValue ]
|
||||
{
|
||||
get
|
||||
{
|
||||
ArgumentOutOfRangeException.ThrowIfLessThan( indexValue, 0 );
|
||||
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual( indexValue, _length );
|
||||
return _collection[ indexValue + _begin ];
|
||||
}
|
||||
}
|
||||
|
||||
public T this[ Index i ]
|
||||
{
|
||||
get
|
||||
{
|
||||
int offset = i.IsFromEnd ? _length - i.Value : i.Value;
|
||||
ArgumentOutOfRangeException.ThrowIfLessThan( offset, 0 );
|
||||
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual( offset, _length );
|
||||
return _collection[ offset + _begin ];
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsReadOnly => true;
|
||||
|
||||
public int Count => _length;
|
||||
|
||||
public bool Contains( T item )
|
||||
{
|
||||
int index = _collection.IndexOf( item );
|
||||
return index >= _begin && index < _length + index;
|
||||
}
|
||||
|
||||
public void CopyTo( T[] array, int arrayIndex )
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull( array );
|
||||
Span<T> span = CollectionsMarshal.AsSpan<T>( _collection ).Slice( _begin, _length );
|
||||
Span<T> target = new Span<T>( array, arrayIndex, _length );
|
||||
span.CopyTo( target );
|
||||
}
|
||||
|
||||
public IEnumerator<T> GetEnumerator()
|
||||
{
|
||||
for( int i = _begin; i < _length; i++ ) {
|
||||
yield return this[ i ];
|
||||
}
|
||||
}
|
||||
|
||||
void ICollection<T>.Add( T item )
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
void ICollection<T>.Clear()
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
bool ICollection<T>.Remove( T item )
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
//-----------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------
|
||||
// file="PartialDictionary.cs"
|
||||
// Project: StgSharp
|
||||
// AuthorGroup: Nitload Space
|
||||
// Copyright (c) Nitload Space. All rights reserved.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//-----------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Text;
|
||||
|
||||
namespace StgSharp.Collections
|
||||
{
|
||||
public partial class PartialDictionary<TKey, TValue> : IDictionary<TKey, TValue>
|
||||
{
|
||||
|
||||
private readonly Dictionary<TKey, TValue> _source;
|
||||
private readonly HashSet<TKey> _keys;
|
||||
private readonly PartialDictionaryValues _values;
|
||||
|
||||
public PartialDictionary( Dictionary<TKey, TValue> source, TKey[] index )
|
||||
{
|
||||
_source = source;
|
||||
_keys = new HashSet<TKey>( index );
|
||||
foreach( TKey item in _keys )
|
||||
{
|
||||
if( !_source.ContainsKey( item ) ) {
|
||||
_source.Add( item, default! );
|
||||
}
|
||||
}
|
||||
_values = new PartialDictionaryValues( this );
|
||||
}
|
||||
|
||||
public PartialDictionary( Dictionary<TKey, TValue> source, HashSet<TKey> keys )
|
||||
{
|
||||
_source = source;
|
||||
_keys = keys;
|
||||
foreach( TKey item in _keys )
|
||||
{
|
||||
if( !_source.ContainsKey( item ) ) {
|
||||
_source.Add( item, default! );
|
||||
}
|
||||
}
|
||||
_values = new PartialDictionaryValues( this );
|
||||
}
|
||||
|
||||
public PartialDictionary(
|
||||
Dictionary<TKey, TValue> source,
|
||||
TKey[] index,
|
||||
IHashMultiplexer<TKey> multiplexer )
|
||||
{
|
||||
_source = source;
|
||||
_keys = new HashSet<TKey>( index );
|
||||
foreach( TKey item in _keys )
|
||||
{
|
||||
if( !_source.ContainsKey( item ) ) {
|
||||
_source.Add( item, default! );
|
||||
}
|
||||
}
|
||||
_values = new PartialDictionaryValues( this );
|
||||
}
|
||||
|
||||
public TValue this[ TKey key ]
|
||||
{
|
||||
get
|
||||
{
|
||||
if( _keys.Contains( key ) ) {
|
||||
return _source[ key ];
|
||||
}
|
||||
throw new KeyNotFoundException();
|
||||
}
|
||||
set
|
||||
{
|
||||
if( _keys.Contains( key ) ) {
|
||||
_source[ key ] = value;
|
||||
}
|
||||
throw new KeyNotFoundException();
|
||||
}
|
||||
}
|
||||
|
||||
public ICollection<TKey> Keys => _keys;
|
||||
|
||||
public ICollection<TValue> Values => _values;
|
||||
|
||||
public int Count => _keys.Count;
|
||||
|
||||
public bool Contains( KeyValuePair<TKey, TValue> item )
|
||||
{
|
||||
return _keys.Contains( item.Key ) && _source.Contains( item );
|
||||
}
|
||||
|
||||
public bool ContainsKey( TKey key )
|
||||
{
|
||||
return _keys.Contains( key );
|
||||
}
|
||||
|
||||
public void CopyTo( KeyValuePair<TKey, TValue>[] array, int arrayIndex )
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
|
||||
{
|
||||
foreach( TKey item in _keys ) {
|
||||
yield return new KeyValuePair<TKey, TValue>( item, _source[ item ] );
|
||||
}
|
||||
}
|
||||
|
||||
public bool TryGetValue( TKey key, out TValue value )
|
||||
{
|
||||
if( _keys.Contains( key ) )
|
||||
{
|
||||
value = _source[ key ];
|
||||
return true;
|
||||
}
|
||||
value = default!;
|
||||
return false;
|
||||
}
|
||||
|
||||
void ICollection<KeyValuePair<TKey, TValue>>.Add( KeyValuePair<TKey, TValue> item )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void ICollection<KeyValuePair<TKey, TValue>>.Clear()
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
bool ICollection<KeyValuePair<TKey, TValue>>.Remove( KeyValuePair<TKey, TValue> item )
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
bool ICollection<KeyValuePair<TKey, TValue>>.IsReadOnly => true;
|
||||
|
||||
void IDictionary<TKey, TValue>.Add( TKey key, TValue value )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
bool IDictionary<TKey, TValue>.Remove( TKey key )
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
//-----------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------
|
||||
// file="PartialDictionaryValues.cs"
|
||||
// Project: StgSharp
|
||||
// AuthorGroup: Nitload Space
|
||||
// Copyright (c) Nitload Space. All rights reserved.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//-----------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace StgSharp.Collections
|
||||
{
|
||||
public partial class PartialDictionary<TKey, TValue>
|
||||
{
|
||||
|
||||
internal sealed class PartialDictionaryValues : ICollection<TValue>
|
||||
{
|
||||
|
||||
private readonly PartialDictionary<TKey, TValue> _values;
|
||||
|
||||
public PartialDictionaryValues( PartialDictionary<TKey, TValue> value )
|
||||
{
|
||||
_values = value;
|
||||
}
|
||||
|
||||
public bool IsReadOnly => true;
|
||||
|
||||
public int Count => _values.Count;
|
||||
|
||||
public bool Contains( TValue item )
|
||||
{
|
||||
foreach( KeyValuePair<TKey, TValue> kvp in _values )
|
||||
{
|
||||
if( kvp.Value != null && kvp.Value.Equals( item ) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void CopyTo( TValue[] array, int arrayIndex )
|
||||
{
|
||||
foreach( KeyValuePair<TKey, TValue> kvp in _values )
|
||||
{
|
||||
array[ arrayIndex ] = kvp.Value;
|
||||
arrayIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerator<TValue> GetEnumerator()
|
||||
{
|
||||
foreach( TKey key in _values._keys ) {
|
||||
yield return _values._source[ key ];
|
||||
}
|
||||
}
|
||||
|
||||
void ICollection<TValue>.Add( TValue item )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void ICollection<TValue>.Clear()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
bool ICollection<TValue>.Remove( TValue item )
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,185 @@
|
||||
//-----------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------
|
||||
// file="RandomAccessibleStack.cs"
|
||||
// Project: StgSharp
|
||||
// AuthorGroup: Nitload Space
|
||||
// Copyright (c) Nitload Space. All rights reserved.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//-----------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace StgSharp.Collections
|
||||
{
|
||||
public class RandomAccessibleStack<T> : IEnumerable<T>
|
||||
{
|
||||
|
||||
private const int DefaultCapacity = 4;
|
||||
|
||||
private T[] _array;
|
||||
private int _size;
|
||||
private int _version;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the RandomAccessStack class that is empty and has the
|
||||
/// default initial capacity.
|
||||
/// </summary>
|
||||
public RandomAccessibleStack()
|
||||
{
|
||||
_array = new T[DefaultCapacity];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the RandomAccessStack class that is empty and has the
|
||||
/// specified initial capacity.
|
||||
/// </summary>
|
||||
public RandomAccessibleStack( int capacity )
|
||||
{
|
||||
if( capacity < 0 ) {
|
||||
throw new ArgumentOutOfRangeException(
|
||||
nameof( capacity ), "Capacity must be non-negative." );
|
||||
}
|
||||
|
||||
_array = new T[capacity];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the element at the specified index in the stack (0 = bottom, Count-1 =
|
||||
/// top).
|
||||
/// </summary>
|
||||
public T this[ int index ]
|
||||
{
|
||||
get
|
||||
{
|
||||
if( index < 0 || index >= _size ) {
|
||||
throw new ArgumentOutOfRangeException( nameof( index ) );
|
||||
}
|
||||
|
||||
return _array[ index ];
|
||||
}
|
||||
/*
|
||||
set
|
||||
{
|
||||
if( index < 0 || index >= _size ) {
|
||||
throw new ArgumentOutOfRangeException( nameof( index ) );
|
||||
}
|
||||
_array[ index ] = value;
|
||||
_version++;
|
||||
}
|
||||
/**/
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of elements contained in the stack.
|
||||
/// </summary>
|
||||
public int Count => _size;
|
||||
|
||||
/// <summary>
|
||||
/// Removes all objects from the stack.
|
||||
/// </summary>
|
||||
public void Clear()
|
||||
{
|
||||
Array.Clear( _array, 0, _size );
|
||||
_size = 0;
|
||||
_version++;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns an enumerator that iterates through the stack from top to bottom. Throws if
|
||||
/// the stack is modified during iteration.
|
||||
/// </summary>
|
||||
public IEnumerator<T> GetEnumerator()
|
||||
{
|
||||
int expectedVersion = _version;
|
||||
for( int i = _size - 1; i >= 0; i-- )
|
||||
{
|
||||
if( expectedVersion != _version ) {
|
||||
throw new InvalidOperationException(
|
||||
"Collection was modified during enumeration." );
|
||||
}
|
||||
|
||||
yield return _array[ i ];
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the object at the top of the stack without removing it.
|
||||
/// </summary>
|
||||
public T Peek()
|
||||
{
|
||||
if( _size == 0 ) {
|
||||
throw new InvalidOperationException( "Stack is empty." );
|
||||
}
|
||||
|
||||
return _array[ _size - 1 ];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes and returns the object at the top of the stack.
|
||||
/// </summary>
|
||||
public T Pop()
|
||||
{
|
||||
if( _size == 0 ) {
|
||||
throw new InvalidOperationException( "Stack is empty." );
|
||||
}
|
||||
|
||||
T item = _array[ --_size ];
|
||||
_array[ _size ] = default!;
|
||||
_version++;
|
||||
return item;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds an item to the top of the stack.
|
||||
/// </summary>
|
||||
public void Push( T item )
|
||||
{
|
||||
if( _size == _array.Length ) {
|
||||
EnsureCapacity( _size + 1 );
|
||||
}
|
||||
|
||||
_array[ _size++ ] = item;
|
||||
_version++;
|
||||
}
|
||||
|
||||
private void EnsureCapacity( int min )
|
||||
{
|
||||
int newCapacity = _array.Length == 0 ? DefaultCapacity : _array.Length * 2;
|
||||
if( newCapacity < min ) {
|
||||
newCapacity = min;
|
||||
}
|
||||
|
||||
Array.Resize( ref _array, newCapacity );
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
//-----------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------
|
||||
// file="StringHashMultiplexer.cs"
|
||||
// Project: StgSharp
|
||||
// AuthorGroup: Nitload Space
|
||||
// Copyright (c) Nitload Space. All rights reserved.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//-----------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Globalization;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
|
||||
namespace StgSharp.Collections
|
||||
{
|
||||
public sealed class StringHashMultiplexer : IHashMultiplexer<string>
|
||||
{
|
||||
|
||||
private int _initCount, _remainedCount, _hashCache, _hashLast;
|
||||
private string _source, _sourceLast;
|
||||
|
||||
public int RemainedMultiplexCount
|
||||
{
|
||||
get => _remainedCount;
|
||||
set => _initCount = value;
|
||||
}
|
||||
|
||||
public void CacheHash( string obj, int count )
|
||||
{
|
||||
_hashCache = ForceComputeHash( obj );
|
||||
_initCount = count;
|
||||
_remainedCount = _initCount;
|
||||
_source = obj;
|
||||
}
|
||||
|
||||
public bool Equals( string x, string y )
|
||||
{
|
||||
return x == y;
|
||||
}
|
||||
|
||||
public void ExtendCache( int count )
|
||||
{
|
||||
_initCount += count;
|
||||
_remainedCount += count;
|
||||
}
|
||||
|
||||
[MethodImpl( MethodImplOptions.AggressiveInlining )]
|
||||
public unsafe int ForceComputeHash( [NotNull] string obj )
|
||||
{
|
||||
int hash;
|
||||
fixed( char* cPtr = obj.AsSpan() ) {
|
||||
hash = InternalIO.Intrinsic.city_hash_simplify( cPtr, obj.Length );
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
public int GetHashCode( string obj )
|
||||
{
|
||||
if( _remainedCount > 0 && ReferenceEquals( _source, obj ) )
|
||||
{
|
||||
_remainedCount--;
|
||||
return _hashCache;
|
||||
}
|
||||
if( ReferenceEquals( _sourceLast, obj ) ) {
|
||||
return _hashLast;
|
||||
}
|
||||
_sourceLast = obj;
|
||||
_hashLast = ForceComputeHash( obj );
|
||||
return _hashLast;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public sealed class ConcurrentStringHashMultiplexer : IHashMultiplexer<string>, IDisposable
|
||||
{
|
||||
|
||||
private bool disposedValue;
|
||||
private readonly ThreadLocal<StringHashMultiplexer> _multiplexers =
|
||||
new( () => new StringHashMultiplexer() );
|
||||
|
||||
public int RemainedMultiplexCount
|
||||
{
|
||||
get => _multiplexers.Value.RemainedMultiplexCount;
|
||||
set => _multiplexers.Value.RemainedMultiplexCount = value;
|
||||
}
|
||||
|
||||
public void CacheHash( string obj, int count )
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
// ~ConcurrentStringHashMultiplexer()
|
||||
// {
|
||||
// Dispose(disposing: false);
|
||||
// }
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose( disposing: true );
|
||||
GC.SuppressFinalize( this );
|
||||
}
|
||||
|
||||
public bool Equals( string x, string y )
|
||||
{
|
||||
return x == y;
|
||||
}
|
||||
|
||||
public void ExtendCache( int count )
|
||||
{
|
||||
_multiplexers.Value.ExtendCache( count );
|
||||
}
|
||||
|
||||
public unsafe int ForceComputeHash( [NotNull] string obj )
|
||||
{
|
||||
int hash;
|
||||
fixed( char* cPtr = obj.AsSpan() ) {
|
||||
hash = InternalIO.Intrinsic.city_hash_simplify( cPtr, obj.Length );
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
public int GetHashCode( string obj )
|
||||
{
|
||||
return _multiplexers.Value.GetHashCode( obj );
|
||||
}
|
||||
|
||||
private void Dispose( bool disposing )
|
||||
{
|
||||
if( !disposedValue )
|
||||
{
|
||||
if( disposing ) {
|
||||
_multiplexers.Dispose();
|
||||
}
|
||||
|
||||
disposedValue = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user