PageRenderTime 53ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/C#/src/Hubble.Framework/Hubble.Framework/DataStructure/IntDictionaryBTree.cs

#
C# | 1560 lines | 1163 code | 287 blank | 110 comment | 186 complexity | 2dfc5300a5b28ddaaedc31594c9f4d20 MD5 | raw file
  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one or more
  3. * contributor license agreements. See the NOTICE file distributed with
  4. * this work for additional information regarding copyright ownership.
  5. * The ASF licenses this file to You under the Apache License, Version 2.0
  6. * (the "License"); you may not use this file except in compliance with
  7. * the License. You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. using System;
  18. using System.Collections;
  19. using System.Collections.Generic;
  20. using System.Text;
  21. using System.Diagnostics;
  22. namespace Hubble.Framework.DataStructure
  23. {
  24. /// <summary>
  25. /// IntDictinary is a special dictinary for Int
  26. /// Base arithmetic: Hash
  27. /// Like BTree
  28. /// </summary>
  29. /// <typeparam name="TValue">Value</typeparam>
  30. public class IntDictionaryBTree<TValue> : IDictionary<int, TValue>
  31. {
  32. enum Operator
  33. {
  34. Query = 0,
  35. Add = 1,
  36. Get = 2,
  37. Set = 3,
  38. Remove = 4,
  39. }
  40. #region DataEntity
  41. [Serializable]
  42. public struct DataEntity
  43. {
  44. public int Used;
  45. public TValue Value;
  46. }
  47. #endregion
  48. #region Node class
  49. /// <summary>
  50. /// Node
  51. /// </summary>
  52. [Serializable]
  53. class Node
  54. {
  55. int _Count;
  56. int _FirstKey;
  57. int _ChildrenNumber;
  58. Node _Parent;
  59. int _ParentIndex;
  60. Node[] _Children;
  61. DataEntity[] _DataList;
  62. int _MaxChildren;
  63. Node _Prev;
  64. Node _Next;
  65. /// <summary>
  66. /// Constructor
  67. /// </summary>
  68. /// <param name="isLeafNode">is leaf node or not</param>
  69. /// <param name="maxChildren">max children number</param>
  70. public Node(bool isLeafNode, int maxChildren)
  71. {
  72. _MaxChildren = maxChildren;
  73. if (isLeafNode)
  74. {
  75. _DataList = new DataEntity[_MaxChildren];
  76. _Children = null;
  77. }
  78. else
  79. {
  80. _DataList = null;
  81. _Children = new Node[_MaxChildren];
  82. }
  83. }
  84. #region Public properties
  85. /// <summary>
  86. /// Get the node is leaf node or not
  87. /// </summary>
  88. public bool IsLeafNode
  89. {
  90. get
  91. {
  92. return DataList != null;
  93. }
  94. }
  95. /// <summary>
  96. /// Count of the data entities below this node
  97. /// </summary>
  98. public int FirstKey
  99. {
  100. get
  101. {
  102. return _FirstKey;
  103. }
  104. set
  105. {
  106. _FirstKey = value;
  107. }
  108. }
  109. /// <summary>
  110. /// Count of the data entities below this node
  111. /// </summary>
  112. public int Count
  113. {
  114. get
  115. {
  116. return _Count;
  117. }
  118. set
  119. {
  120. _Count = value;
  121. }
  122. }
  123. /// <summary>
  124. /// The children number of this node
  125. /// If this is leaf node, it is the number of data
  126. /// </summary>
  127. public int ChildrenNumber
  128. {
  129. get
  130. {
  131. return _ChildrenNumber;
  132. }
  133. set
  134. {
  135. _ChildrenNumber = value;
  136. }
  137. }
  138. /// <summary>
  139. /// The parent node of this node.
  140. /// If parent is null, this is the root node
  141. /// </summary>
  142. public Node Parent
  143. {
  144. get
  145. {
  146. return _Parent;
  147. }
  148. set
  149. {
  150. _Parent = value;
  151. }
  152. }
  153. /// <summary>
  154. /// Index of parent node
  155. /// </summary>
  156. public int ParentIndex
  157. {
  158. get
  159. {
  160. return _ParentIndex;
  161. }
  162. set
  163. {
  164. _ParentIndex = value;
  165. }
  166. }
  167. /// <summary>
  168. /// Children of this node.
  169. /// If children is null, this is leaf node
  170. /// </summary>
  171. public Node[] Children
  172. {
  173. get
  174. {
  175. return _Children;
  176. }
  177. }
  178. /// <summary>
  179. /// Data list
  180. /// only for leaf nodes
  181. /// </summary>
  182. public DataEntity[] DataList
  183. {
  184. get
  185. {
  186. return _DataList;
  187. }
  188. }
  189. /// <summary>
  190. /// Only leaf node use it.
  191. /// Prev leaf node
  192. /// </summary>
  193. public Node Prev
  194. {
  195. get
  196. {
  197. return _Prev;
  198. }
  199. set
  200. {
  201. _Prev = value;
  202. }
  203. }
  204. /// <summary>
  205. /// Only leaf node use it.
  206. /// Next leaf node
  207. /// </summary>
  208. public Node Next
  209. {
  210. get
  211. {
  212. return _Next;
  213. }
  214. set
  215. {
  216. _Next = value;
  217. }
  218. }
  219. #endregion
  220. }
  221. #endregion
  222. #region Collection classes
  223. [Serializable()]
  224. public sealed class KeyCollection : ICollection<int>, ICollection
  225. {
  226. private IntDictionaryBTree<TValue> _Dictionary;
  227. public KeyCollection(IntDictionaryBTree<TValue> dictionary)
  228. {
  229. _Dictionary = dictionary;
  230. }
  231. #region ICollection members
  232. public void CopyTo(Array array, int index)
  233. {
  234. if (array == null)
  235. {
  236. throw new ArgumentNullException("array is null!");
  237. }
  238. if (array.GetLowerBound(0) != 0)
  239. {
  240. throw new ArgumentException("Arg_NonZeroLowerBound");
  241. }
  242. if (index < 0 || index > array.Length)
  243. {
  244. throw new ArgumentOutOfRangeException(string.Format("index={0} out of range", index));
  245. }
  246. if (array.Length - index < _Dictionary.Count)
  247. {
  248. throw new ArgumentException("Arg_ArrayPlusOffTooSmall");
  249. }
  250. int i = 0;
  251. int[] keys = array as int[];
  252. foreach (int key in _Dictionary.GetKeys())
  253. {
  254. keys[i] = key;
  255. i++;
  256. }
  257. }
  258. public int Count
  259. {
  260. get
  261. {
  262. return _Dictionary.Count;
  263. }
  264. }
  265. public bool IsSynchronized
  266. {
  267. get
  268. {
  269. return false;
  270. }
  271. }
  272. public object SyncRoot
  273. {
  274. get
  275. {
  276. return false;
  277. }
  278. }
  279. #endregion
  280. #region IEnumerable members
  281. public IEnumerator GetEnumerator()
  282. {
  283. foreach (int key in _Dictionary.GetKeys())
  284. {
  285. yield return key;
  286. }
  287. }
  288. #endregion
  289. #region ICollection<int> Members
  290. public void Add(int item)
  291. {
  292. throw new Exception("Not supported KeyCollectionSet");
  293. }
  294. public void Clear()
  295. {
  296. throw new Exception("Not supported KeyCollectionSet");
  297. }
  298. public bool Contains(int item)
  299. {
  300. return _Dictionary.ContainsKey(item);
  301. }
  302. public void CopyTo(int[] array, int index)
  303. {
  304. if (array == null)
  305. {
  306. throw new ArgumentNullException("array is null!");
  307. }
  308. if (array.GetLowerBound(0) != 0)
  309. {
  310. throw new ArgumentException("Arg_NonZeroLowerBound");
  311. }
  312. if (index < 0 || index > array.Length)
  313. {
  314. throw new ArgumentOutOfRangeException(string.Format("index={0} out of range", index));
  315. }
  316. if (array.Length - index < _Dictionary.Count)
  317. {
  318. throw new ArgumentException("Arg_ArrayPlusOffTooSmall");
  319. }
  320. int i = 0;
  321. foreach (int key in _Dictionary.GetKeys())
  322. {
  323. array[i] = key;
  324. i++;
  325. }
  326. }
  327. public bool IsReadOnly
  328. {
  329. get
  330. {
  331. return true;
  332. }
  333. }
  334. public bool Remove(int item)
  335. {
  336. throw new Exception("Not supported KeyCollectionSet");
  337. }
  338. #endregion
  339. #region IEnumerable<int> Members
  340. IEnumerator<int> IEnumerable<int>.GetEnumerator()
  341. {
  342. foreach (int key in _Dictionary.GetKeys())
  343. {
  344. yield return key;
  345. }
  346. }
  347. #endregion
  348. }
  349. [Serializable()]
  350. public sealed class ValueCollection : ICollection<TValue>, ICollection
  351. {
  352. private IntDictionaryBTree<TValue> _Dictionary;
  353. public ValueCollection(IntDictionaryBTree<TValue> dictionary)
  354. {
  355. _Dictionary = dictionary;
  356. }
  357. #region ICollection members
  358. public void CopyTo(Array array, int index)
  359. {
  360. if (array == null)
  361. {
  362. throw new ArgumentNullException("array is null!");
  363. }
  364. if (array.GetLowerBound(0) != 0)
  365. {
  366. throw new ArgumentException("Arg_NonZeroLowerBound");
  367. }
  368. if (index < 0 || index > array.Length)
  369. {
  370. throw new ArgumentOutOfRangeException(string.Format("index={0} out of range", index));
  371. }
  372. if (array.Length - index < _Dictionary.Count)
  373. {
  374. throw new ArgumentException("Arg_ArrayPlusOffTooSmall");
  375. }
  376. int i = 0;
  377. TValue[] values = array as TValue[];
  378. foreach (TValue value in _Dictionary.GetValues())
  379. {
  380. values[i] = value;
  381. i++;
  382. }
  383. }
  384. public int Count
  385. {
  386. get
  387. {
  388. return _Dictionary.Count;
  389. }
  390. }
  391. public bool IsSynchronized
  392. {
  393. get
  394. {
  395. return false;
  396. }
  397. }
  398. public object SyncRoot
  399. {
  400. get
  401. {
  402. return false;
  403. }
  404. }
  405. #endregion
  406. #region IEnumerable members
  407. public IEnumerator GetEnumerator()
  408. {
  409. foreach (TValue value in _Dictionary.GetValues())
  410. {
  411. yield return value;
  412. }
  413. }
  414. #endregion
  415. #region ICollection<TValue> Members
  416. public void Add(TValue item)
  417. {
  418. throw new Exception("Not supported KeyCollectionSet");
  419. }
  420. public void Clear()
  421. {
  422. throw new Exception("Not supported KeyCollectionSet");
  423. }
  424. public bool Contains(TValue item)
  425. {
  426. return _Dictionary.ContainsValue(item);
  427. }
  428. public void CopyTo(TValue[] array, int index)
  429. {
  430. if (array == null)
  431. {
  432. throw new ArgumentNullException("array is null!");
  433. }
  434. if (array.GetLowerBound(0) != 0)
  435. {
  436. throw new ArgumentException("Arg_NonZeroLowerBound");
  437. }
  438. if (index < 0 || index > array.Length)
  439. {
  440. throw new ArgumentOutOfRangeException(string.Format("index={0} out of range", index));
  441. }
  442. if (array.Length - index < _Dictionary.Count)
  443. {
  444. throw new ArgumentException("Arg_ArrayPlusOffTooSmall");
  445. }
  446. int i = 0;
  447. foreach (TValue value in _Dictionary.GetValues())
  448. {
  449. array[i] = value;
  450. i++;
  451. }
  452. }
  453. public bool IsReadOnly
  454. {
  455. get
  456. {
  457. return true;
  458. }
  459. }
  460. public bool Remove(TValue item)
  461. {
  462. throw new Exception("Not supported KeyCollectionSet");
  463. }
  464. #endregion
  465. #region IEnumerable<TValue> Members
  466. IEnumerator<TValue> IEnumerable<TValue>.GetEnumerator()
  467. {
  468. foreach (TValue value in _Dictionary.GetValues())
  469. {
  470. yield return value;
  471. }
  472. }
  473. #endregion
  474. }
  475. #endregion
  476. #region Private fields
  477. private int _Height = 0; //Height of the tree
  478. private int _MaxChildren; //Max children number of each node.
  479. private List<int> _PowPool; //Caculate Pow and Log
  480. private int _MinFreeKey = 0; //Used by getting free key automaticly.
  481. /// <summary>
  482. /// The root node
  483. /// </summary>
  484. Node _Root = null;
  485. #endregion
  486. #region Public properties
  487. /// <summary>
  488. /// The maximum children number of every nodes
  489. /// </summary>
  490. public int MaxChildren
  491. {
  492. get
  493. {
  494. return _MaxChildren;
  495. }
  496. set
  497. {
  498. _MaxChildren = value;
  499. _PowPool = new List<int>();
  500. long pow = 0;
  501. int times = 0;
  502. _PowPool.Add((int)pow);
  503. pow = (long)Math.Pow(_MaxChildren, ++times);
  504. while (pow <= int.MaxValue)
  505. {
  506. _PowPool.Add((int)pow);
  507. pow = (long)Math.Pow(_MaxChildren, ++times);
  508. }
  509. }
  510. }
  511. /// <summary>
  512. /// The height of the tree
  513. /// </summary>
  514. public int Height
  515. {
  516. get
  517. {
  518. return _Height;
  519. }
  520. }
  521. #endregion
  522. #region Constructor
  523. public IntDictionaryBTree(int maxChildren)
  524. {
  525. MaxChildren = maxChildren;
  526. }
  527. public IntDictionaryBTree()
  528. : this(2048)
  529. {
  530. }
  531. #endregion
  532. #region Private methods
  533. private Node GetFirstLeafNode()
  534. {
  535. if (_Root == null)
  536. {
  537. return null;
  538. }
  539. Node cur = _Root;
  540. while (!cur.IsLeafNode)
  541. {
  542. foreach (Node node in cur.Children)
  543. {
  544. if (node != null)
  545. {
  546. cur = node;
  547. break;
  548. }
  549. }
  550. }
  551. return cur;
  552. }
  553. private Node GetLastLeafNode()
  554. {
  555. if (_Root == null)
  556. {
  557. return null;
  558. }
  559. Node cur = _Root;
  560. while (!cur.IsLeafNode)
  561. {
  562. for (int i = MaxChildren - 1; i >= 0; i--)
  563. {
  564. Node node = cur.Children[i];
  565. if (node != null)
  566. {
  567. cur = node;
  568. break;
  569. }
  570. }
  571. }
  572. return cur;
  573. }
  574. private Node GetPrevLeafNode(Node curLeafNode)
  575. {
  576. Node cur = curLeafNode;
  577. int index = cur.ParentIndex;
  578. cur = cur.Parent;
  579. while (cur != null)
  580. {
  581. while (!cur.IsLeafNode)
  582. {
  583. while (--index >= 0)
  584. {
  585. if (cur.Children[index] != null)
  586. {
  587. cur = cur.Children[index];
  588. index = (int)MaxChildren;
  589. break;
  590. }
  591. }
  592. if (index < 0)
  593. {
  594. break;
  595. }
  596. }
  597. if (cur.IsLeafNode)
  598. {
  599. return cur;
  600. }
  601. index = cur.ParentIndex;
  602. cur = cur.Parent;
  603. }
  604. return null;
  605. }
  606. private Node GetNextLeafNode(Node curLeafNode)
  607. {
  608. Node cur = curLeafNode;
  609. int index = cur.ParentIndex;
  610. cur = cur.Parent;
  611. while (cur != null)
  612. {
  613. while (!cur.IsLeafNode)
  614. {
  615. while (++index < (int)MaxChildren)
  616. {
  617. if (cur.Children[index] != null)
  618. {
  619. cur = cur.Children[index];
  620. index = -1;
  621. break;
  622. }
  623. }
  624. if (index >= (int)MaxChildren)
  625. {
  626. break;
  627. }
  628. }
  629. if (cur.IsLeafNode)
  630. {
  631. return cur;
  632. }
  633. index = cur.ParentIndex;
  634. cur = cur.Parent;
  635. }
  636. return null;
  637. }
  638. private IEnumerable<KeyValuePair<int, TValue>> GetKeyValuePairs()
  639. {
  640. Node cur = GetFirstLeafNode();
  641. while (cur != null)
  642. {
  643. int i = 0;
  644. foreach (DataEntity entity in cur.DataList)
  645. {
  646. if (entity.Used != 0)
  647. {
  648. yield return new KeyValuePair<int, TValue>(i + cur.FirstKey, entity.Value);
  649. }
  650. i++;
  651. }
  652. cur = cur.Next;
  653. }
  654. }
  655. public IEnumerable<TValue> GetValuesDesc()
  656. {
  657. Node cur = GetLastLeafNode();
  658. while (cur != null)
  659. {
  660. for (int i = MaxChildren - 1; i >= 0; i--)
  661. {
  662. DataEntity entity = cur.DataList[i];
  663. if (entity.Used != 0)
  664. {
  665. yield return entity.Value;
  666. }
  667. }
  668. cur = cur.Prev;
  669. }
  670. }
  671. private IEnumerable<TValue> GetValues()
  672. {
  673. Node cur = GetFirstLeafNode();
  674. while (cur != null)
  675. {
  676. foreach (DataEntity entity in cur.DataList)
  677. {
  678. if (entity.Used != 0)
  679. {
  680. yield return entity.Value;
  681. }
  682. }
  683. cur = cur.Next;
  684. }
  685. }
  686. private IEnumerable<int> GetKeys()
  687. {
  688. Node cur = GetFirstLeafNode();
  689. while (cur != null)
  690. {
  691. int i = 0;
  692. foreach (DataEntity entity in cur.DataList)
  693. {
  694. if (entity.Used != 0)
  695. {
  696. yield return i + cur.FirstKey;
  697. }
  698. i++;
  699. }
  700. cur = cur.Next;
  701. }
  702. }
  703. /// <summary>
  704. /// Construct the tree
  705. /// </summary>
  706. /// <param name="key"></param>
  707. private void Construct(int key)
  708. {
  709. #region Math.Log(key, MaxChildren) + 1
  710. int height = 0;
  711. foreach (int pow in _PowPool)
  712. {
  713. if (key >= pow)
  714. {
  715. height++;
  716. }
  717. else
  718. {
  719. break;
  720. }
  721. }
  722. #endregion
  723. if (height <= Height)
  724. {
  725. return;
  726. }
  727. if (Height == 0)
  728. {
  729. Node node = new Node(true, MaxChildren);
  730. Node leafNode = node;
  731. node.FirstKey = (key / MaxChildren) * MaxChildren;
  732. if (height == 1)
  733. {
  734. _Root = node;
  735. _Height = height;
  736. return;
  737. }
  738. else
  739. {
  740. _Height = 1;
  741. while (--height > 0)
  742. {
  743. Node pNode = new Node(false, MaxChildren);
  744. node.Parent = pNode;
  745. _Height++;
  746. #region Caculate pow and index
  747. //long mPowh = (long)Math.Pow(MaxChildren, Height);
  748. //int index = (int)((int)(key % mPowh) / (int)(mPowh / MaxChildren));
  749. int index;
  750. if (height >= _PowPool.Count)
  751. {
  752. index = (int)(key / _PowPool[_PowPool.Count - 1]);
  753. }
  754. else
  755. {
  756. index = (int)((key % _PowPool[height]) / (_PowPool[height] / MaxChildren));
  757. }
  758. #endregion
  759. pNode.Children[index] = node;
  760. node.ParentIndex = index;
  761. node = pNode;
  762. }
  763. _Root = node;
  764. //Add friend
  765. Node cur = leafNode;
  766. if (cur.IsLeafNode)
  767. {
  768. Node prev = GetPrevLeafNode(cur);
  769. Node next = GetNextLeafNode(cur);
  770. if (prev != null)
  771. {
  772. cur.Prev = prev;
  773. cur.Next = prev.Next;
  774. prev.Next = cur;
  775. if (cur.Next != null)
  776. {
  777. cur.Next.Prev = cur;
  778. }
  779. }
  780. else if (next != null)
  781. {
  782. cur.Next = next;
  783. cur.Prev = next.Prev;
  784. next.Prev = cur;
  785. if (cur.Prev != null)
  786. {
  787. cur.Prev.Next = cur;
  788. }
  789. }
  790. }
  791. }
  792. }
  793. else
  794. {
  795. while (height > Height)
  796. {
  797. Node pNode = new Node(false, MaxChildren);
  798. pNode.Count = _Root.Count;
  799. _Root.Parent = pNode;
  800. _Height++;
  801. pNode.Children[0] = _Root;
  802. _Root.ParentIndex = 0;
  803. _Root = pNode;
  804. }
  805. }
  806. }
  807. private bool Get(int key, out Node leafNode, out int index, Operator opr)
  808. {
  809. System.Diagnostics.Debug.Assert(opr == Operator.Get || opr == Operator.Query || opr == Operator.Remove);
  810. int height = Height;
  811. Node cur = _Root;
  812. leafNode = null;
  813. index = 0;
  814. while (height > 0)
  815. {
  816. #region Caculate pow and index
  817. //long mPowh = (long)Math.Pow(MaxChildren, Height);
  818. //int index = (int)((int)(key % mPowh) / (int)(mPowh / MaxChildren));
  819. if (height >= _PowPool.Count)
  820. {
  821. index = (int)(key / _PowPool[_PowPool.Count - 1]);
  822. }
  823. else
  824. {
  825. index = (int)((key % _PowPool[height]) / (_PowPool[height] / MaxChildren));
  826. }
  827. #endregion
  828. if (height > 1)
  829. {
  830. //Branch node
  831. if (cur.Children[index] == null)
  832. {
  833. return false;
  834. }
  835. else
  836. {
  837. cur = cur.Children[index];
  838. }
  839. }
  840. else
  841. {
  842. //Leaf node
  843. leafNode = cur;
  844. return cur.DataList[index].Used != 0;
  845. }
  846. height--;
  847. }
  848. return false;
  849. }
  850. /// <summary>
  851. /// Do something with the tree
  852. /// </summary>
  853. /// <param name="key">key</param>
  854. /// <param name="value">value</param>
  855. /// <param name="opr">operator type</param>
  856. /// <returns>if find key return true</returns>
  857. private bool Set(int key, TValue value, Operator opr)
  858. {
  859. System.Diagnostics.Debug.Assert(opr == Operator.Add || opr == Operator.Set);
  860. if (key < 0)
  861. {
  862. throw new System.ArgumentException("Key must not be less than zero!");
  863. }
  864. int height = Height;
  865. Node cur = _Root;
  866. while (height > 0)
  867. {
  868. #region Caculate pow and index
  869. //long mPowh = (long)Math.Pow(MaxChildren, Height);
  870. //int index = (int)((int)(key % mPowh) / (int)(mPowh / MaxChildren));
  871. int index;
  872. if (height >= _PowPool.Count)
  873. {
  874. index = (int)(key / _PowPool[_PowPool.Count - 1]);
  875. }
  876. else
  877. {
  878. index = (int)((key % _PowPool[height]) / (_PowPool[height] / MaxChildren));
  879. }
  880. #endregion
  881. if (height > 1)
  882. {
  883. //Branch node
  884. if (cur.Children[index] == null)
  885. {
  886. Node node = new Node(height == 2, MaxChildren);
  887. if (node.IsLeafNode)
  888. {
  889. node.FirstKey = (key / MaxChildren) * MaxChildren;
  890. }
  891. cur.Children[index] = node;
  892. node.ParentIndex = index;
  893. node.Parent = cur;
  894. cur = node;
  895. //Add friend
  896. if (cur.IsLeafNode)
  897. {
  898. Node prev = GetPrevLeafNode(cur);
  899. Node next = GetNextLeafNode(cur);
  900. if (prev != null)
  901. {
  902. cur.Prev = prev;
  903. cur.Next = prev.Next;
  904. prev.Next = cur;
  905. if (cur.Next != null)
  906. {
  907. cur.Next.Prev = cur;
  908. }
  909. }
  910. else if (next != null)
  911. {
  912. cur.Next = next;
  913. cur.Prev = next.Prev;
  914. next.Prev = cur;
  915. if (cur.Prev != null)
  916. {
  917. cur.Prev.Next = cur;
  918. }
  919. }
  920. }
  921. }
  922. else
  923. {
  924. cur = cur.Children[index];
  925. }
  926. }
  927. else
  928. {
  929. //Leaf node
  930. if (opr == Operator.Set || (cur.DataList[index].Used == 0 && opr == Operator.Add))
  931. {
  932. //Set value
  933. int used = cur.DataList[index].Used;
  934. cur.DataList[index].Used = 1;
  935. cur.DataList[index].Value = value;
  936. //Inc count
  937. if (used == 0)
  938. {
  939. while (cur != null)
  940. {
  941. cur.Count++;
  942. cur = cur.Parent;
  943. }
  944. }
  945. return true;
  946. }
  947. else
  948. {
  949. throw new System.ArgumentException("An item with the same key has already been added.");
  950. }
  951. }
  952. height--;
  953. }
  954. return false;
  955. }
  956. #endregion
  957. #region Public methods
  958. public int SortInsert(int key, TValue value)
  959. {
  960. _MinFreeKey = key;
  961. return Add(value);
  962. }
  963. /// <summary>
  964. /// Add value by automatic key
  965. /// </summary>
  966. /// <param name="value">value</param>
  967. /// <returns>The key that allocates automaticly</returns>
  968. public int Add(TValue value)
  969. {
  970. Node leafNode;
  971. int index;
  972. int key = 0;
  973. int existsKey;
  974. if (Get(_MinFreeKey, out leafNode, out index, Operator.Query))
  975. {
  976. existsKey = _MinFreeKey;
  977. Node cur = leafNode;
  978. bool find = false;
  979. int lastKey = cur.FirstKey;
  980. while (cur != null)
  981. {
  982. if (lastKey != cur.FirstKey)
  983. {
  984. //hole of leaf nodes
  985. key = lastKey;
  986. find = true;
  987. break;
  988. }
  989. if (cur.Count < MaxChildren)
  990. {
  991. int i = 0;
  992. foreach (DataEntity entity in cur.DataList)
  993. {
  994. if (entity.Used == 0 && cur.FirstKey + i > existsKey)
  995. {
  996. key = cur.FirstKey + i;
  997. find = true;
  998. break;
  999. }
  1000. i++;
  1001. }
  1002. if (find)
  1003. {
  1004. break;
  1005. }
  1006. }
  1007. lastKey = cur.FirstKey + MaxChildren;
  1008. cur = cur.Next;
  1009. }
  1010. if (!find)
  1011. {
  1012. key = this.Count;
  1013. }
  1014. }
  1015. else
  1016. {
  1017. key = _MinFreeKey;
  1018. }
  1019. Add(key, value);
  1020. _MinFreeKey = key + 1;
  1021. return key;
  1022. }
  1023. #endregion
  1024. #region IDictionary<int,TValue> Members
  1025. public void Add(int key, TValue value)
  1026. {
  1027. Construct(key);
  1028. Set(key, value, Operator.Add);
  1029. }
  1030. public bool ContainsKey(int key)
  1031. {
  1032. Node leafNode;
  1033. int index;
  1034. return Get(key, out leafNode, out index, Operator.Query);
  1035. }
  1036. public bool ContainsValue(TValue value)
  1037. {
  1038. foreach (TValue v in GetValues())
  1039. {
  1040. if (typeof(TValue).IsClass)
  1041. {
  1042. if (v == null && value == null)
  1043. {
  1044. return true;
  1045. }
  1046. else if (v == null || value == null)
  1047. {
  1048. continue;
  1049. }
  1050. else
  1051. {
  1052. if (v.Equals(value))
  1053. {
  1054. return true;
  1055. }
  1056. }
  1057. }
  1058. else
  1059. {
  1060. if (v.Equals(value))
  1061. {
  1062. return true;
  1063. }
  1064. }
  1065. }
  1066. return false;
  1067. }
  1068. public ICollection<int> Keys
  1069. {
  1070. get
  1071. {
  1072. return new KeyCollection(this);
  1073. }
  1074. }
  1075. public bool Remove(int key)
  1076. {
  1077. Node leafNode;
  1078. int index;
  1079. if (!Get(key, out leafNode, out index, Operator.Remove))
  1080. {
  1081. return false;
  1082. }
  1083. else
  1084. {
  1085. if (leafNode != null)
  1086. {
  1087. leafNode.DataList[index].Used = 0;
  1088. Node cur = leafNode;
  1089. //Dec node count including parent nodes
  1090. while (cur != null)
  1091. {
  1092. cur.Count--;
  1093. cur = cur.Parent;
  1094. }
  1095. cur = leafNode;
  1096. int i = 0;
  1097. //Remove empty nodes
  1098. while (cur != null)
  1099. {
  1100. i = cur.ParentIndex;
  1101. if (cur.Count <= 0)
  1102. {
  1103. if (cur.IsLeafNode)
  1104. {
  1105. //If cur node is leaf node, remove prev and next
  1106. if (cur.Prev != null)
  1107. {
  1108. cur.Prev.Next = cur.Next;
  1109. }
  1110. if (cur.Next != null)
  1111. {
  1112. cur.Next.Prev = cur.Prev;
  1113. }
  1114. }
  1115. Node parent = cur.Parent;
  1116. if (parent == null)
  1117. {
  1118. //Root node empty
  1119. _Root = null;
  1120. _Height = 0;
  1121. }
  1122. else
  1123. {
  1124. parent.Children[i] = null;
  1125. }
  1126. }
  1127. else
  1128. {
  1129. break;
  1130. }
  1131. cur = cur.Parent;
  1132. }
  1133. if (_MinFreeKey > key)
  1134. {
  1135. _MinFreeKey = key;
  1136. }
  1137. return true;
  1138. }
  1139. else
  1140. {
  1141. return false;
  1142. }
  1143. }
  1144. }
  1145. public bool TryGetValue(int key, out TValue value)
  1146. {
  1147. Node leafNode;
  1148. int index;
  1149. if (!Get(key, out leafNode, out index, Operator.Get))
  1150. {
  1151. value = default(TValue);
  1152. return false;
  1153. }
  1154. else
  1155. {
  1156. value = leafNode.DataList[index].Value;
  1157. return true;
  1158. }
  1159. }
  1160. public ICollection<TValue> Values
  1161. {
  1162. get
  1163. {
  1164. return new ValueCollection(this);
  1165. }
  1166. }
  1167. public TValue this[int key]
  1168. {
  1169. get
  1170. {
  1171. Node leafNode;
  1172. int index;
  1173. if (!Get(key, out leafNode, out index, Operator.Get))
  1174. {
  1175. throw new System.Collections.Generic.KeyNotFoundException("The given key was not present in the dictionary.");
  1176. }
  1177. else
  1178. {
  1179. return leafNode.DataList[index].Value;
  1180. }
  1181. }
  1182. set
  1183. {
  1184. Construct(key);
  1185. Set(key, value, Operator.Set);
  1186. }
  1187. }
  1188. #endregion
  1189. #region ICollection<KeyValuePair<int,TValue>> Members
  1190. public void Add(KeyValuePair<int, TValue> item)
  1191. {
  1192. Add(item.Key, item.Value);
  1193. }
  1194. public void Clear()
  1195. {
  1196. _Root = null;
  1197. _Height = 0;
  1198. }
  1199. public bool Contains(KeyValuePair<int, TValue> item)
  1200. {
  1201. return ContainsKey(item.Key);
  1202. }
  1203. public void CopyTo(KeyValuePair<int, TValue>[] array, int arrayIndex)
  1204. {
  1205. if (array == null)
  1206. {
  1207. throw new ArgumentNullException("array is null!");
  1208. }
  1209. if (array.GetLowerBound(0) != 0)
  1210. {
  1211. throw new ArgumentException("Arg_NonZeroLowerBound");
  1212. }
  1213. if (arrayIndex < 0 || arrayIndex > array.Length)
  1214. {
  1215. throw new ArgumentOutOfRangeException(string.Format("index={0} out of range", arrayIndex));
  1216. }
  1217. if (array.Length - arrayIndex < this.Count)
  1218. {
  1219. throw new ArgumentException("Arg_ArrayPlusOffTooSmall");
  1220. }
  1221. int i = 0;
  1222. foreach (KeyValuePair<int, TValue> kv in this.GetKeyValuePairs())
  1223. {
  1224. array[i] = kv;
  1225. i++;
  1226. }
  1227. }
  1228. public int Count
  1229. {
  1230. get
  1231. {
  1232. if (_Root == null)
  1233. {
  1234. return 0;
  1235. }
  1236. else
  1237. {
  1238. return _Root.Count;
  1239. }
  1240. }
  1241. }
  1242. public bool IsReadOnly
  1243. {
  1244. get
  1245. {
  1246. return false;
  1247. }
  1248. }
  1249. public bool Remove(KeyValuePair<int, TValue> item)
  1250. {
  1251. return Remove(item.Key);
  1252. }
  1253. #endregion
  1254. #region IEnumerable<KeyValuePair<int,TValue>> Members
  1255. public IEnumerator<KeyValuePair<int, TValue>> GetEnumerator()
  1256. {
  1257. foreach (KeyValuePair<int, TValue> kv in this.GetKeyValuePairs())
  1258. {
  1259. yield return kv;
  1260. }
  1261. }
  1262. #endregion
  1263. #region IEnumerable Members
  1264. System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
  1265. {
  1266. foreach (KeyValuePair<int, TValue> kv in this.GetKeyValuePairs())
  1267. {
  1268. yield return kv;
  1269. }
  1270. }
  1271. #endregion
  1272. }
  1273. }