cache.cs 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. //
  2. // assembly: System
  3. // namespace: System.Text.RegularExpressions
  4. // file: cache.cs
  5. //
  6. // author: Dan Lewis ([email protected])
  7. // (c) 2002
  8. using System;
  9. using System.Collections;
  10. namespace System.Text.RegularExpressions {
  11. class FactoryCache {
  12. public FactoryCache (int capacity) {
  13. this.capacity = capacity;
  14. this.factories = new Hashtable (capacity);
  15. this.mru_list = new MRUList ();
  16. }
  17. public void Add (string pattern, RegexOptions options, IMachineFactory factory) {
  18. lock (this) {
  19. Key k = new Key (pattern, options);
  20. while (factories.Count >= capacity) {
  21. object victim = mru_list.Evict ();
  22. if (victim != null)
  23. factories.Remove ((Key)victim);
  24. }
  25. factories[k] = factory;
  26. mru_list.Use (k);
  27. }
  28. }
  29. public IMachineFactory Lookup (string pattern, RegexOptions options) {
  30. lock (this) {
  31. Key k = new Key (pattern, options);
  32. if (factories.Contains (k)) {
  33. mru_list.Use (k);
  34. return (IMachineFactory)factories[k];
  35. }
  36. }
  37. return null;
  38. }
  39. private int capacity;
  40. private Hashtable factories;
  41. private MRUList mru_list;
  42. class Key {
  43. public string pattern;
  44. public RegexOptions options;
  45. public Key (string pattern, RegexOptions options) {
  46. this.pattern = pattern;
  47. this.options = options;
  48. }
  49. public override int GetHashCode () {
  50. return pattern.GetHashCode () ^ (int)options;
  51. }
  52. public override bool Equals (object o) {
  53. if (o == null || !(o is Key))
  54. return false;
  55. Key k = (Key)o;
  56. return options == k.options && pattern.Equals (k.pattern);
  57. }
  58. public override string ToString () {
  59. return "('" + pattern + "', [" + options + "])";
  60. }
  61. }
  62. }
  63. class MRUList {
  64. public MRUList () {
  65. head = tail = null;
  66. }
  67. public void Use (object o) {
  68. Node node;
  69. if (head == null) {
  70. node = new Node (o);
  71. head = tail = node;
  72. return;
  73. }
  74. node = head;
  75. while (node != null && !o.Equals (node.value))
  76. node = node.previous;
  77. if (node == null)
  78. node = new Node (o);
  79. else {
  80. if (node == head)
  81. return;
  82. if (node == tail)
  83. tail = node.next;
  84. else
  85. node.previous.next = node.next;
  86. node.next.previous = node.previous;
  87. }
  88. head.next = node;
  89. node.previous = head;
  90. node.next = null;
  91. head = node;
  92. }
  93. public object Evict () {
  94. if (tail == null)
  95. return null;
  96. object o = tail.value;
  97. tail = tail.next;
  98. if (tail == null)
  99. head = null;
  100. else
  101. tail.previous = null;
  102. return o;
  103. }
  104. private Node head, tail;
  105. private class Node {
  106. public object value;
  107. public Node previous, next;
  108. public Node (object value) {
  109. this.value = value;
  110. }
  111. }
  112. }
  113. }