Vector.vala 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. namespace Invercargill.DataStructures {
  2. public class Vector<T> : Enumerable<T>, Lot<T>, ReadOnlyCollection<T>, ReadOnlyAddressable<T>, Collection<T>, Addressable<T>, AddressableCollection<T> {
  3. private T[] array;
  4. private uint n_items = 0;
  5. private SafeReadFunc<T>? safe_read;
  6. private SafeWriteFunc<T>? safe_write;
  7. private RWLock rw_lock;
  8. private const uint INITIAL_SIZE = 2;
  9. public Vector() {
  10. rw_lock = RWLock();
  11. array = new T[INITIAL_SIZE];
  12. safe_read = get_safe_read_function_for<T>();
  13. safe_write = get_safe_write_function_for<T>();
  14. }
  15. public override uint? peek_count() {
  16. return n_items;
  17. }
  18. public override uint count(PredicateDelegate<T>? predicate = null) {
  19. if(predicate == null) {
  20. return n_items;
  21. }
  22. return base.count(predicate);
  23. }
  24. public override EnumerableInfo get_info() {
  25. return new EnumerableInfo.infer_ultimate (this, EnumerableCategory.IN_MEMORY);
  26. }
  27. public override uint length { get { return n_items; }}
  28. public override Tracker<T> get_tracker() {
  29. return new AddressableTracker<T>(this);
  30. }
  31. public override T[] to_array () {
  32. rw_lock.reader_lock();
  33. var a2 = new T[n_items];
  34. if(safe_write != null) {
  35. for(uint i = 0; i < n_items; i++) {
  36. safe_write(a2, i, array_read(i));
  37. }
  38. }
  39. else {
  40. for(uint i = 0; i < n_items; i++) {
  41. a2[i] = array[i];
  42. }
  43. }
  44. rw_lock.reader_unlock();
  45. return a2;
  46. }
  47. public void add(T item) {
  48. rw_lock.writer_lock();
  49. ensure_room(1);
  50. array_write(n_items, item);
  51. n_items++;
  52. rw_lock.writer_unlock();
  53. }
  54. public override void add_all(Enumerable<T> items) {
  55. rw_lock.writer_lock();
  56. foreach (var item in items) {
  57. ensure_room(1);
  58. array_write(n_items, item);
  59. n_items++;
  60. }
  61. rw_lock.writer_unlock();
  62. }
  63. public new T @get(uint index) throws IndexError {
  64. IndexError? e = null;
  65. rw_lock.reader_lock();
  66. if(index < 0) {
  67. e = new IndexError.INDEX_EXCEEDS_LOWER_BOUNDS("Index is less than 0");
  68. }
  69. else if(index >= n_items) {
  70. e = new IndexError.INDEX_EXCEEDS_UPPER_BOUNDS(@"Tried to access index $(index) on a vector with $(n_items) item(s)");
  71. }
  72. else {
  73. var item = array_read(index);
  74. rw_lock.reader_unlock();
  75. return item;
  76. }
  77. rw_lock.reader_unlock();
  78. throw e;
  79. }
  80. public bool try_get(uint index, out T value) {
  81. rw_lock.reader_lock();
  82. if(index >= 0 && index < n_items) {
  83. value = array_read(index);
  84. rw_lock.reader_unlock();
  85. return true;
  86. }
  87. rw_lock.reader_unlock();
  88. value = null;
  89. return false;
  90. }
  91. public new void @set(uint index, T value) throws IndexError {
  92. IndexError? e = null;
  93. rw_lock.writer_lock();
  94. if(index < 0) {
  95. e = new IndexError.INDEX_EXCEEDS_LOWER_BOUNDS("Index is less than 0");
  96. }
  97. else if(index >= n_items) {
  98. e = new IndexError.INDEX_EXCEEDS_UPPER_BOUNDS(@"Tried to set index $(index) on a vector with $(n_items) item(s)");
  99. }
  100. else {
  101. array_write(index, value);
  102. rw_lock.writer_unlock();
  103. return;
  104. }
  105. rw_lock.writer_unlock();
  106. throw e;
  107. }
  108. private void ensure_room(uint items) {
  109. if(array.length <= n_items + items) {
  110. array.resize(array.length * 2);
  111. }
  112. }
  113. public void insert_at(uint index, T item) throws IndexError {
  114. rw_lock.writer_lock();
  115. if(index > n_items) {
  116. rw_lock.writer_unlock();
  117. throw new IndexError.INDEX_EXCEEDS_UPPER_BOUNDS(@"Insertion is only allowed at indexes that are less than or equal to the count of the vector. Tried to insert at index $(index), vector has count of $(n_items)");
  118. }
  119. ensure_room(1);
  120. safely_move_items_in_array<T>(array, index, index+1, n_items-index);
  121. array_write(index, item);
  122. n_items++;
  123. rw_lock.writer_unlock();
  124. }
  125. public void remove_at(uint index) throws IndexError {
  126. var e = remove_internal(index);
  127. if(e != null) {
  128. throw e;
  129. }
  130. }
  131. private IndexError? remove_internal(uint index) {
  132. IndexError? e = null;
  133. rw_lock.writer_lock();
  134. if(index >= n_items) {
  135. e = new IndexError.INDEX_EXCEEDS_UPPER_BOUNDS(@"Tried to set index $(index) on a vector with $(n_items) item(s)");
  136. }
  137. else {
  138. for(uint i = index; i < n_items; i++) {
  139. if(i+1 < n_items) {
  140. array_write(i, array_read(i+1));
  141. continue;
  142. }
  143. array[i] = null;
  144. }
  145. n_items --;
  146. }
  147. rw_lock.writer_unlock();
  148. return e;
  149. }
  150. public override T last(owned PredicateDelegate<T>? predicate = null) throws SequenceError {
  151. if(predicate != null) {
  152. return base.last((owned)predicate);
  153. }
  154. SequenceError? e = null;
  155. rw_lock.reader_lock();
  156. if(n_items == 0) {
  157. e = new SequenceError.NO_ELEMENTS("The sequence contains no elements");
  158. }
  159. else {
  160. var item = array_read(n_items -1);
  161. rw_lock.reader_unlock();
  162. return item;
  163. }
  164. rw_lock.reader_unlock();
  165. throw e;
  166. }
  167. public override T? last_or_default(owned PredicateDelegate<T>? predicate = null) {
  168. if(predicate != null) {
  169. return base.last_or_default((owned)predicate);
  170. }
  171. rw_lock.reader_lock();
  172. if(n_items == 0) {
  173. rw_lock.reader_unlock();
  174. return null;
  175. }
  176. else {
  177. var item = array_read(n_items -1);
  178. rw_lock.reader_unlock();
  179. return item;
  180. }
  181. }
  182. private void array_write(uint index, T item) {
  183. if(safe_write != null) {
  184. safe_write(array, index, item);
  185. return;
  186. }
  187. array[index] = item;
  188. }
  189. private T array_read(uint index) {
  190. if(safe_read != null) {
  191. return safe_read(array, index);
  192. }
  193. return array[index];
  194. }
  195. public uint? first_index_of(PredicateDelegate<T> predicate) {
  196. var i = 0;
  197. foreach (var item in this) {
  198. if(predicate(item)) {
  199. return i;
  200. }
  201. i++;
  202. }
  203. return null;
  204. }
  205. public void remove_first_where(Invercargill.PredicateDelegate<T> predicate) {
  206. var index = first_index_of(predicate);
  207. if (index != null) {
  208. remove_internal(index);
  209. }
  210. }
  211. public void remove_all_where(Invercargill.PredicateDelegate<T> predicate) {
  212. with_positions()
  213. .where(i => predicate(i.item))
  214. .select<int>(i => i.position)
  215. .iterate(i => remove_internal(i));
  216. }
  217. public void clear() {
  218. n_items = 0;
  219. array = new T[INITIAL_SIZE];
  220. }
  221. }
  222. }