首页 > 其他分享 >TreeMap实现一致性hash

TreeMap实现一致性hash

时间:2024-09-26 16:15:01浏览次数:8  
标签:node map hash TreeMap key 一致性 return null Left

  using System.Security.Cryptography;
  using System.Text;

  namespace ConsoleApp7
  {
      internal class Program
      {
          static void Main(string[] args)
          {
              var servers = new List<string>
              {
                  "192.168.1.2",
                  "192.168.1.3",
                  "192.168.1.4",
              };

              var consistentHash = new ConsistentHash<string, string>(100, servers,x => x.ToString());
              var node = consistentHash.Get("2");

              Console.WriteLine("Hello, World!");
          }
      }

      public class ConsistentHash<K, V> where K : IComparable<K> where V : IComparable<V>
      {
          private readonly int vNodeCount;
          private readonly TreeMap<long, V> circle;
          private readonly IEnumerable<V> nodes;
          private readonly Func<V, string> keyGetter;

          public ConsistentHash(int vNodeCount, IEnumerable<V> nodes, Func<V, string> keyGetter)
          {
              this.vNodeCount = vNodeCount;
              this.circle = new TreeMap<long, V>();
              this.nodes = nodes;
              this.keyGetter = keyGetter;
              this.BuildTreeMap();
          }

          private void BuildTreeMap()
          {
              foreach (var node in nodes)
              {
                  for (int i = 0; i < vNodeCount; i++)
                  {
                      var hashCode = HashKey(WrapKey(keyGetter(node), i));
                      circle.Put(hashCode, node);
                  }
              }
          }

          public V Get(string key)
          {
              if (key == null) throw new ArgumentNullException(nameof(key));

              var hashCode = HashKey(key);
              var entry = circle.TailMap(hashCode).First();
              return entry.Value;
          }

          private string WrapKey(string key, int index)
          {
              if (key == null) throw new ArgumentNullException(nameof(key));

              return $"{key},{index}";
          }

          private long HashKey(string key)
          {
              if (key == null) throw new ArgumentNullException(nameof(key));

              var bytes = MD5.HashData(Encoding.UTF8.GetBytes(key.ToString()!));

              var hashCode = ((int)(bytes[3] & 0xFF) << 24)
                  | ((int)(bytes[2] & 0xFF) << 16)
                  | ((int)(bytes[1] & 0xFF) << 8)
                  | (bytes[0] & 0xFF);

              return hashCode;
          }

      }

      /// <summary>
      /// Map abstraction
      /// </summary>
      /// <typeparam name="K">Key data type</typeparam>
      /// <typeparam name="V">Value data type</typeparam>
      public interface Map<K, V> : IEnumerable<KeyValuePair<K, V>> where K : IComparable<K> where V : IComparable<V>
      {

          /// <summary>
          /// Clears the map
          /// </summary>
          void Clear();

          /// <summary>
          /// Checks if the map contains key
          /// </summary>
          /// <param name="key">key to look for</param>
          /// <returns>true if key exists, false otherwise</returns>
          bool ContainsKey(K key);

          /// <summary>
          /// Checks if the map contains value
          /// </summary>
          /// <param name="value">value to look for</param>
          /// <returns>true if value exists, false otherwise</returns>
          bool ContainsValue(V value);

          /// <summary>
          /// Checks if the map is equal to given object
          /// </summary>
          /// <param name="o">object to compare to</param>
          /// <returns>true if objects are equal</returns>
          bool Equals(object o);

          /// <summary>
          /// Gets the value associated with the given key
          /// </summary>
          /// <param name="key">key to look for</param>
          /// <returns>value associated with the key</returns>
          V Get(K key);

          /// <summary>
          /// Checks if the map is empty or not
          /// </summary>
          /// <returns>true if the map is empty, false otherwise</returns>
          bool IsEmpty();

          /// <summary>
          /// Gets all the keys contained in this map
          /// </summary>
          /// <returns>List of keys</returns>
          ICollection<K> Keys();

          /// <summary>
          /// Inserts (if key doesn't exist) or updates the value with the given key
          /// </summary>
          /// <param name="key">key to insert or update</param>
          /// <param name="value">value to insert</param>
          /// <returns>newly inserted value</returns>
          V Put(K key, V value);

          /// <summary>
          /// Inserts all keys and values from the given map to this map
          /// </summary>
          /// <param name="map">map with values to be inserted</param>
          void PutAll(Map<K, V> map);

          /// <summary>
          /// Deletes an entry from the map
          /// </summary>
          /// <param name="key">key to delete</param>
          /// <returns>deleted value</returns>
          V Remove(K key);

          /// <summary>
          /// Gets the number of entries in this map
          /// </summary>
          /// <returns>number of entries</returns>
          int Size();

          /// <summary>
          /// Gets all the values contained in this map
          /// </summary>
          /// <returns>List of values</returns>
          ICollection<V> Values();
      }

      /// <summary>
      /// Sorted map abstraction
      /// </summary>
      /// <typeparam name="K">Key data type</typeparam>
      /// <typeparam name="V">Value data type</typeparam>
      interface SortedMap<K, V> : Map<K, V> where K : IComparable<K> where V : IComparable<V>
      {

          /// <summary>
          /// Returns the first key in this map
          /// </summary>
          /// <returns>first key</returns>
          K FirstKey();

          /// <summary>
          /// Returns all entries that are strictly less than the specified key
          /// </summary>
          /// <param name="to">key up to which to collect elements</param>
          /// <returns>map containing entries</returns>
          SortedMap<K, V> HeadMap(K to);

          /// <summary>
          /// Returns the last key in this map
          /// </summary>
          /// <returns>last key</returns>
          K LastKey();

          /// <summary>
          /// Returns all entries from the map ranging from fromKey (inclusive) to toKey (exclusive)
          /// </summary>
          /// <param name="fromKey"></param>
          /// <param name="toKey"></param>
          /// <returns>map containing entries</returns>
          SortedMap<K, V> SubMap(K fromKey, K toKey);

          /// <summary>
          /// Returns all entries from the map that are greater or equal to the specified key
          /// </summary>
          /// <param name="from">key to start collecting elements from</param>
          /// <returns>map containing elements</returns>
          SortedMap<K, V> TailMap(K from);
      }

      /// <summary>
      /// TreeMap implementation
      /// </summary>
      /// <typeparam name="K">Key data type</typeparam>
      /// <typeparam name="V">Value data type</typeparam>
      class TreeMap<K, V> : SortedMap<K, V> where K : IComparable<K> where V : IComparable<V>
      {

          // number of nodes in this tree
          protected int Count { get; private set; }

          // root node
          protected Node<K, V> Root;

          // comparator used to compare keys
          protected IComparer<K> Comparator;

          /// <summary>
          /// Default class constructor. Automatically creates a comparator to use when comparing keys
          /// </summary>
          public TreeMap()
          {
              Comparator = Comparer<K>.Create((a, b) => a.CompareTo(b));
          }

          /// <summary>
          /// Class constructor. Sets the comparator to use when comparing keys to the specified one
          /// </summary>
          /// <param name="Comparator">comparator to use</param>
          public TreeMap(IComparer<K> Comparator)
          {
              this.Comparator = Comparator;
          }

          /// <summary>
          /// Clears the map
          /// </summary>
          public void Clear()
          {
              Root = null;
              Count = 0;
          }

          /// <summary>
          /// Checks if the map contains specified key
          /// </summary>
          /// <param name="key">key to look for</param>
          /// <returns>true if key exists, false otherwise</returns>
          public bool ContainsKey(K key)
          {
              if (ReferenceEquals(key, null))
              {
                  throw new ArgumentException("Key cannot be null at ContainsKey(K key)");
              }

              Node<K, V> node = Root;

              while (!ReferenceEquals(node, null))
              {
                  int compare = Comparator.Compare(key, node.Key);

                  if (compare < 0)
                  {
                      node = node.Left;
                      continue;
                  }
                  else if (compare > 0)
                  {
                      node = node.Right;
                      continue;
                  }

                  return true;
              }

              return false;
          }

          /// <summary>
          /// Checks if the map contains specified value
          /// </summary>
          /// <param name="value">value to look for</param>
          /// <returns>true if the value exists, false otherwise</returns>
          public bool ContainsValue(V value)
          {
              if (ReferenceEquals(value, null))
              {
                  throw new ArgumentException("Value cannot be null at ContainsValue(V value)");
              }

              return ContainsValueRecursive(Root, value);
          }

          /// <summary>
          /// Helper method for ContainsValue(). Checks if the value exists starting from the specified node
          /// </summary>
          /// <param name="node">node to start looking from</param>
          /// <param name="value">value to look for</param>
          /// <returns>true is the value exists in the sub-tree, false otherwise</returns>
          private bool ContainsValueRecursive(Node<K, V> node, V value)
          {
              if (ReferenceEquals(node, null))
              {
                  return false;
              }

              if (node.Value.CompareTo(value) == 0)
              {
                  return true;
              }

              bool left = ContainsValueRecursive(node.Left, value);
              bool right = ContainsValueRecursive(node.Right, value);

              return left ? left : right;
          }

          /// <summary>
          /// Gets the first key in this map
          /// </summary>
          /// <returns>first key</returns>
          public K FirstKey()
          {
              Node<K, V> node = Root;

              while (!ReferenceEquals(node, null))
              {
                  if (ReferenceEquals(node.Left, null))
                  {
                      return node.Key;
                  }

                  node = node.Left;
              }

              return default(K);
          }

          /// <summary>
          /// Gets the value associated with the specified key
          /// </summary>
          /// <param name="key">key to look for</param>
          /// <returns>value associated with the key, default value of V if not found</returns>
          public V Get(K key)
          {
              if (ReferenceEquals(key, null))
              {
                  throw new ArgumentException("Key cannot be null at Get(K key)");
              }

              Node<K, V> node = Root;

              while (!ReferenceEquals(node, null))
              {
                  int compare = Comparator.Compare(key, node.Key);

                  if (compare < 0)
                  {
                      node = node.Left;
                      continue;
                  }
                  else if (compare > 0)
                  {
                      node = node.Right;
                      continue;
                  }

                  return node.Value;
              }

              return default(V);
          }

          /// <summary>
          /// Gets all the elements that are strictly less than the specified key
          /// </summary>
          /// <param name="to">key up to which elements will be added</param>
          /// <returns>map of elements</returns>
          public SortedMap<K, V> HeadMap(K to)
          {
              if (ReferenceEquals(to, null))
              {
                  throw new ArgumentException("Parameter to cannot be null at HeadMap(K to)");
              }

              TreeMap<K, V> map = new TreeMap<K, V>();

              AddNodesRecursive(to, Root, map, false, true);

              return map;
          }

          /// <summary>
          /// Checks if the map is empty or not
          /// </summary>
          /// <returns>true if the map is empty, false if not</returns>
          public bool IsEmpty()
          {
              return Count == 0;
          }

          /// <summary>
          /// Gets all keys stored in this map
          /// </summary>
          /// <returns>collection of keys</returns>
          public ICollection<K> Keys()
          {
              List<K> list = new List<K>();

              AddKeysRecursive(Root, list);

              return list;
          }

          /// <summary>
          /// Helper method for Keys(). Adds all keys to the collection starting from specified node
          /// </summary>
          /// <param name="node">node to start from</param>
          /// <param name="collection">collection to add keys to</param>
          private void AddKeysRecursive(Node<K, V> node, ICollection<K> collection)
          {
              if (ReferenceEquals(node, null))
              {
                  return;
              }

              AddKeysRecursive(node.Left, collection);

              collection.Add(node.Key);

              AddKeysRecursive(node.Right, collection);
          }

          /// <summary>
          /// Gets the last key in this map
          /// </summary>
          /// <returns>last key</returns>
          public K LastKey()
          {
              Node<K, V> node = Root;

              while (!ReferenceEquals(node, null))
              {
                  if (ReferenceEquals(node.Right, null))
                  {
                      return node.Key;
                  }

                  node = node.Right;
              }

              return default(K);
          }

          /// <summary>
          /// Inserts (if key doesn't exist) or updates the value with the given key
          /// </summary>
          /// <param name="key">key to insert or update</param>
          /// <param name="value">value to insert</param>
          /// <returns>newly inserted value</returns>
          public V Put(K key, V value)
          {
              if (ReferenceEquals(key, null))
              {
                  throw new ArgumentException("Key cannot be null at Put(K key, V value)");
              }

              Root = PutRecursive(key, value, Root);

              return value;
          }

          /// <summary>
          /// Helper method for Put(). Recursively adds an element
          /// </summary>
          /// <param name="key">key to put</param>
          /// <param name="value">value to put</param>
          /// <param name="node">node to put to</param>
          /// <returns>node with inserted value</returns>
          private Node<K, V> PutRecursive(K key, V value, Node<K, V> node)
          {
              if (ReferenceEquals(node, null))
              {
                  Count++;
                  return new Node<K, V>(key, value);
              }

              int comp = Comparator.Compare(key, node.Key);

              if (comp < 0)
              {
                  node.Left = PutRecursive(key, value, node.Left);

                  if (Height(node.Left) - Height(node.Right) == 2)
                  {
                      int comp2 = Comparator.Compare(key, node.Left.Key);
                      node = (comp2 < 0) ? RightRotation(node) : DoubleRightRotation(node);
                  }
              }
              else if (comp > 0)
              {
                  node.Right = PutRecursive(key, value, node.Right);

                  if (Height(node.Right) - Height(node.Left) == 2)
                  {
                      int comp2 = Comparator.Compare(node.Right.Key, key);
                      node = (comp2 < 0) ? LeftRotation(node) : DoubleLeftRotation(node);
                  }
              }
              else
              {
                  node.Value = value;
                  return node;
              }

              node.Height = Math.Max(Height(node.Left), Height(node.Right)) + 1;

              return node;
          }

          /// <summary>
          /// Puts all elements found in the specified map to this map
          /// </summary>
          /// <param name="map">map with elements to put</param>
          public void PutAll(Map<K, V> map)
          {
              foreach (KeyValuePair<K, V> x in map)
              {
                  Put(x.Key, x.Value);
              }
          }

          /// <summary>
          /// Removes the value associated with the specified key from the map
          /// </summary>
          /// <param name="key">key to remove</param>
          /// <returns>removed value</returns>
          public V Remove(K key)
          {
              if (ReferenceEquals(key, null))
              {
                  throw new ArgumentException("Key cannot be null at Remove(K key)");
              }

              Node<K, V> removed = new Node<K, V>();

              Root = RemoveRecursive(key, removed, Root);

              return removed.Value;
          }

          /// <summary>
          /// Helper method for Remove(). Recursively removes an element
          /// </summary>
          /// <param name="key">key to remove</param>
          /// <param name="removed">removed node</param>
          /// <param name="node">node to start from</param>
          /// <returns>modified node</returns>
          private Node<K, V> RemoveRecursive(K key, Node<K, V> removed, Node<K, V> node)
          {
              if (ReferenceEquals(node, null))
              {
                  return null;
              }

              int compare = Comparator.Compare(key, node.Key);

              if (compare < 0)
              {
                  node.Left = RemoveRecursive(key, removed, node.Left);
              }
              else if (compare > 0)
              {
                  node.Right = RemoveRecursive(key, removed, node.Right);
              }
              else if (node.Left != null && node.Right != null)
              {
                  Node<K, V> maxNode = GetMax(node.Left);

                  removed.Key = node.Key;
                  removed.Value = node.Value;

                  node.Key = maxNode.Key;
                  node.Value = maxNode.Value;
                  node.Left = RemoveMax(node.Left);

                  Count--;
              }
              else
              {
                  node = (node.Left != null) ? node.Left : node.Right;
                  Count--;
              }

              // re-balance the tree
              if (ReferenceEquals(node, null))
              {
                  return null;
              }

              node.Height = Math.Max(Height(node.Left), Height(node.Right)) + 1;

              int balance = Height(node.Left) - Height(node.Right);

              if (balance > 1 && Height(node.Left.Left) - Height(node.Left.Right) >= 0)
              {
                  return RightRotation(node);
              }

              if (balance > 1 && Height(node.Left.Left) - Height(node.Left.Right) < 0)
              {
                  node.Left = LeftRotation(node.Left);
                  return RightRotation(node);
              }

              if (balance < -1 && Height(node.Right.Left) - Height(node.Right.Right) <= 0)
              {
                  return LeftRotation(node);
              }

              if (balance < -1 && Height(node.Right.Left) - Height(node.Right.Right) > 0)
              {
                  node.Right = RightRotation(node.Right);
                  return LeftRotation(node);
              }

              return node;
          }

          /// <summary>
          /// Gets the number of elements in this map
          /// </summary>
          /// <returns>number of elements</returns>
          public int Size()
          {
              return Count;
          }

          /// <summary>
          /// Gets all emenents ranging from fromKey (inclusive) and toKey (exclusive)
          /// </summary>
          /// <param name="fromKey">key to start from</param>
          /// <param name="toKey">key to stop at</param>
          /// <returns>map of elements</returns>
          public SortedMap<K, V> SubMap(K fromKey, K toKey)
          {
              if (ReferenceEquals(fromKey, null) || ReferenceEquals(toKey, null))
              {
                  throw new ArgumentException("No parameter can be null at SubMap(K fromKey, K toKey)");
              }

              TreeMap<K, V> map = new TreeMap<K, V>();

              AddNodesRecursiveSubMap(fromKey, toKey, Root, map);

              return map;
          }

          /// <summary>
          /// Helper method for SubMap(). Recursively adds elements to the specified map
          /// </summary>
          /// <param name="from">starting key</param>
          /// <param name="to">ending key</param>
          /// <param name="node">node to start from</param>
          /// <param name="map">map to add to</param>
          private void AddNodesRecursiveSubMap(K from, K to, Node<K, V> node, SortedMap<K, V> map)
          {
              if (ReferenceEquals(node, null))
              {
                  return;
              }

              AddNodesRecursiveSubMap(from, to, node.Left, map);

              int compare1 = Comparator.Compare(from, node.Key);
              int compare2 = Comparator.Compare(to, node.Key);

              if (compare1 <= 0 && compare2 > 0)
              {
                  map.Put(node.Key, node.Value);
              }

              AddNodesRecursiveSubMap(from, to, node.Right, map);
          }

          /// <summary>
          /// Gets all elements that are greater of equal to the specified element
          /// </summary>
          /// <param name="from">key to start from</param>
          /// <returns>map of elements</returns>
          public SortedMap<K, V> TailMap(K from)
          {
              if (ReferenceEquals(from, null))
              {
                  throw new ArgumentException("Parameter from cannot be null at TailMap(K from)");
              }

              TreeMap<K, V> map = new TreeMap<K, V>();

              AddNodesRecursive(from, Root, map, true, false);

              return map;
          }

          /// <summary>
          /// Helper method for TailMap() and HeadMap(). Adds elements to the specified map
          /// </summary>
          /// <param name="key">comparison key</param>
          /// <param name="node">node to start from</param>
          /// <param name="map">map to add to</param>
          /// <param name="inclusive">is the key inclusive</param>
          /// <param name="lesser">should it add lesser elements than the specified key</param>
          private void AddNodesRecursive(K key, Node<K, V> node, SortedMap<K, V> map, bool inclusive, bool lesser)
          {
              if (ReferenceEquals(node, null))
              {
                  return;
              }

              AddNodesRecursive(key, node.Left, map, inclusive, lesser);

              int compare = Comparator.Compare(key, node.Key);

              if (compare < 0 && !lesser)
              {
                  map.Put(node.Key, node.Value);
              }
              else if (compare > 0 && lesser)
              {
                  map.Put(node.Key, node.Value);
              }
              else if (compare == 0 && inclusive)
              {
                  map.Put(node.Key, node.Value);
              }

              AddNodesRecursive(key, node.Right, map, inclusive, lesser);
          }

          /// <summary>
          /// Gets all the values stored in this map
          /// </summary>
          /// <returns>collection of values</returns>
          public ICollection<V> Values()
          {
              List<V> list = new List<V>();

              AddValuesRecursive(Root, list);

              return list;
          }

          /// <summary>
          /// Helper method for Values(). Recursively adds values to a collection starting from the specified node
          /// </summary>
          /// <param name="node">node to start from</param>
          /// <param name="collection">collection to add to</param>
          private void AddValuesRecursive(Node<K, V> node, ICollection<V> collection)
          {
              if (ReferenceEquals(node, null))
              {
                  return;
              }

              AddValuesRecursive(node.Left, collection);

              collection.Add(node.Value);

              AddValuesRecursive(node.Right, collection);
          }

          /// <summary>
          /// Removes the greatest element from a sub-tree
          /// </summary>
          /// <param name="node">root node of the sub-tree</param>
          /// <returns>modified node</returns>
          protected Node<K, V> RemoveMax(Node<K, V> node)
          {
              if (ReferenceEquals(node, null))
              {
                  return null;
              }
              else if (node.Right != null)
              {
                  node.Right = RemoveMax(node.Right);
                  return node;
              }
              else
              {
                  return node.Left;
              }
          }

          /// <summary>
          /// Gets the greatest element in a sub-tree
          /// </summary>
          /// <param name="node">root node of the sub-tree</param>
          /// <returns>greatest element</returns>
          protected Node<K, V> GetMax(Node<K, V> node)
          {
              Node<K, V> parent = null;

              while (!ReferenceEquals(node, null))
              {
                  parent = node;
                  node = node.Right;
              }

              return parent;
          }

          // ************* TREE TORATIONS ************* //
          protected Node<K, V> RightRotation(Node<K, V> n2)
          {
              Node<K, V> n1 = n2.Left;

              n2.Left = n1.Right;
              n1.Right = n2;

              n2.Height = Math.Max(Height(n2.Left), Height(n2.Right)) + 1;
              n1.Height = Math.Max(Height(n1.Left), Height(n2)) + 1;

              return n1;
          }

          protected Node<K, V> LeftRotation(Node<K, V> n1)
          {
              Node<K, V> n2 = n1.Right;

              n1.Right = n2.Left;
              n2.Left = n1;

              n1.Height = Math.Max(Height(n1.Left), Height(n1.Right)) + 1;
              n2.Height = Math.Max(Height(n2.Right), Height(n1)) + 1;

              return n2;
          }

          protected Node<K, V> DoubleRightRotation(Node<K, V> n3)
          {
              n3.Left = LeftRotation(n3.Left);

              return RightRotation(n3);
          }

          protected Node<K, V> DoubleLeftRotation(Node<K, V> n1)
          {
              n1.Right = RightRotation(n1.Right);

              return LeftRotation(n1);
          }

          protected int Height(Node<K, V> node)
          {
              return ReferenceEquals(node, null) ? -1 : node.Height;
          }
          // ************* END OF TREE TORATIONS ************* //

          // ************ ITERATION LOGIC ************ //
          public IEnumerator<KeyValuePair<K, V>> GetEnumerator()
          {
              List<KeyValuePair<K, V>> nodes = new List<KeyValuePair<K, V>>();

              AddNodesRecursive(Root, nodes);

              foreach (KeyValuePair<K, V> node in nodes)
              {
                  yield return node;
              }
          }

          private void AddNodesRecursive(Node<K, V> node, ICollection<KeyValuePair<K, V>> collection)
          {
              if (ReferenceEquals(node, null))
              {
                  return;
              }

              AddNodesRecursive(node.Left, collection);

              collection.Add(new KeyValuePair<K, V>(node.Key, node.Value));

              AddNodesRecursive(node.Right, collection);
          }

          System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
          {
              return GetEnumerator();
          }

          // ************ END OF ITERATION LOGIC ************ //

          /// <summary>
          /// Tree node class containing key, value, height of the node, left and right nodes
          /// </summary>
          /// <typeparam name="K">Key data type</typeparam>
          /// <typeparam name="V">Value data type</typeparam>
          protected class Node<K, V>
          {

              public K Key { get; set; }
              public V Value { get; set; }

              public Node<K, V> Left { get; set; }
              public Node<K, V> Right { get; set; }

              public int Height { get; set; }

              public Node() { }

              public Node(K Key, V Value) : this(Key, Value, null, null) { }

              public Node(K Key, V Value, Node<K, V> Left, Node<K, V> Right)
              {
                  this.Key = Key;
                  this.Value = Value;
                  this.Left = Left;
                  this.Right = Right;
              }
          }
      }
  }

标签:node,map,hash,TreeMap,key,一致性,return,null,Left
From: https://www.cnblogs.com/readafterme/p/18433619

相关文章

  • 服务器数据恢复—SAN环境下LUN Mapping错误导致写操作不互斥,文件系统一致性出错的数据
    服务器数据恢复环境:SAN环境下一台存储设备中有一组由6块硬盘组建的RAID6磁盘阵列,划分若干LUN,MAP到不同业务的SOLARIS操作系统服务器上。服务器故障:用户新增了一台服务器,将存储中的某个LUN映射到新增加的这台服务器上。这个映射的LUN其实之前已经MAP到其他SOLARIS操作系统的服务......
  • module collections has no attribute Hashable PyDocx 库报错
    项目背景在测试PyDocx代码时```pythonfrompydocximportPyDocXhtml=PyDocX.to_html("test.docx")withopen("test.html",'w',encoding="utf-8")asf:f.write(html)```发生错误:Traceback(mostrecentcalllast):File"D:......
  • 章14——Hashtable
    键和值为NULL时会抛出空指针异常。KEY重复且无NULL时同样会替换,和HashMap是一样的。按照2倍+1的规律去扩容与HASHMAP对比PROPERTIES,也是MAP接口的实现类,是Hashtable的子类.properties文件通常是用于数据库的配置文件,储存数据库的用户名密码等东西详细可见博客园博客:Java......
  • 架构师手写代码:分享数据库原子性与一致性实现方案(不再背概念)
    数据库事务的原子性和一致性是数据库管理系统(DBMS)中确保数据完整性和可靠性的两个关键属性。下面是这两个属性的基本概念和实现逻辑:肖哥弹架构跟大家“弹弹”数据库设计技巧,关注公号回复'mvcc'获得手写数据库事务代码欢迎点赞,点赞,点赞。关注公号Solomon肖哥弹架构获取......
  • F - Takahashi in Narrow Road
    F-TakahashiinNarrowRoadProblemStatementThereisaroadextendingeastandwest,and$N$personsareontheroad.Theroadextendsinfinitelylongtotheeastandwestfromapointcalledtheorigin.The$i$-thperson$(1\leqi\leqN)$isinitial......
  • HashMap和HashTable
    HashMaphashMap基于哈希表,底层结果由数组实现,添加到map里的元素以key-value的形式存储在数组中,在数组中key-value已一个实体的形式存储, 也就是继承至map接口中的entry,下图是map源码enrty既然hashMap是基于哈希表,就会出现一个问题,就是哈希值重复,专业术语叫哈......
  • [ABC371F] Takahashi in Narrow Road 题解
    洛谷题目链接Atcoder题目链接前言这道题我赛时想到了正解并打了出来,然后因为把\(l\)打成了\(1\)导致WA\(\times23\),然后又没场切六道题(悲。然后赛后有人说正解是珂朵莉树/线段树,然而我是珂朵莉树\(+\)线段树,呵。题意数轴上有\(n\)个人,第\(i\)个人初始在\(X_i\)处,每一次操作......
  • Java集合类面试题:Map接口(链表、HashMap、红黑树)
    收集大量Java经典面试题目......
  • 题解:AT_abc372_f [ABC372F] Teleporting Takahashi 2
    题意给出一个\(n\)个点的有向图,点\(i\)连向点\((i+1)\),点\(n\)连向点\(1\)。再给你\(m\)条额外边。你的初始位置为\(1\),问你移动\(k\)步的不同方案数(仅当路径不同时两个方案不同)。思路先想怎样暴力转移,显然移动\(k\)步到达一个点的方案数为所有跟这个点连边的移......
  • 项目实战:一步步实现高效缓存与数据库的数据一致性方案
    Hello,大家好!我是积极活泼、爱分享技术的小米!今天我们来聊一聊在做个人项目时,如何保证数据一致性。数据一致性问题,尤其是涉及缓存与数据库的场景,可以说是我们日常开发中经常遇到的挑战之一。今天我将以一个简单的场景为例,带大家一步步了解如何解决这个问题——既能高效利用缓存,又能......