root / trunk / Pithos.Core / Agents / CollectionExtensions.cs @ 126f90b3
History | View | Annotate | Download (7.3 kB)
1 | 255f5f86 | Panagiotis Kanavos | #region |
---|---|---|---|
2 | 255f5f86 | Panagiotis Kanavos | /* ----------------------------------------------------------------------- |
3 | 255f5f86 | Panagiotis Kanavos | * <copyright file="CollectionExtensions.cs" company="GRNet"> |
4 | 255f5f86 | Panagiotis Kanavos | * |
5 | 255f5f86 | Panagiotis Kanavos | * Copyright 2011-2012 GRNET S.A. All rights reserved. |
6 | 255f5f86 | Panagiotis Kanavos | * |
7 | 255f5f86 | Panagiotis Kanavos | * Redistribution and use in source and binary forms, with or |
8 | 255f5f86 | Panagiotis Kanavos | * without modification, are permitted provided that the following |
9 | 255f5f86 | Panagiotis Kanavos | * conditions are met: |
10 | 255f5f86 | Panagiotis Kanavos | * |
11 | 255f5f86 | Panagiotis Kanavos | * 1. Redistributions of source code must retain the above |
12 | 255f5f86 | Panagiotis Kanavos | * copyright notice, this list of conditions and the following |
13 | 255f5f86 | Panagiotis Kanavos | * disclaimer. |
14 | 255f5f86 | Panagiotis Kanavos | * |
15 | 255f5f86 | Panagiotis Kanavos | * 2. Redistributions in binary form must reproduce the above |
16 | 255f5f86 | Panagiotis Kanavos | * copyright notice, this list of conditions and the following |
17 | 255f5f86 | Panagiotis Kanavos | * disclaimer in the documentation and/or other materials |
18 | 255f5f86 | Panagiotis Kanavos | * provided with the distribution. |
19 | 255f5f86 | Panagiotis Kanavos | * |
20 | 255f5f86 | Panagiotis Kanavos | * |
21 | 255f5f86 | Panagiotis Kanavos | * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS |
22 | 255f5f86 | Panagiotis Kanavos | * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
23 | 255f5f86 | Panagiotis Kanavos | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
24 | 255f5f86 | Panagiotis Kanavos | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR |
25 | 255f5f86 | Panagiotis Kanavos | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
26 | 255f5f86 | Panagiotis Kanavos | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
27 | 255f5f86 | Panagiotis Kanavos | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF |
28 | 255f5f86 | Panagiotis Kanavos | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
29 | 255f5f86 | Panagiotis Kanavos | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
30 | 255f5f86 | Panagiotis Kanavos | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
31 | 255f5f86 | Panagiotis Kanavos | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
32 | 255f5f86 | Panagiotis Kanavos | * POSSIBILITY OF SUCH DAMAGE. |
33 | 255f5f86 | Panagiotis Kanavos | * |
34 | 255f5f86 | Panagiotis Kanavos | * The views and conclusions contained in the software and |
35 | 255f5f86 | Panagiotis Kanavos | * documentation are those of the authors and should not be |
36 | 255f5f86 | Panagiotis Kanavos | * interpreted as representing official policies, either expressed |
37 | 255f5f86 | Panagiotis Kanavos | * or implied, of GRNET S.A. |
38 | 255f5f86 | Panagiotis Kanavos | * </copyright> |
39 | 255f5f86 | Panagiotis Kanavos | * ----------------------------------------------------------------------- |
40 | 255f5f86 | Panagiotis Kanavos | */ |
41 | 255f5f86 | Panagiotis Kanavos | #endregion |
42 | b9f5b594 | Panagiotis Kanavos | using System.Collections.Concurrent; |
43 | fec5da06 | Panagiotis Kanavos | using System.Diagnostics.Contracts; |
44 | 759bd3c4 | Panagiotis Kanavos | using Pithos.Interfaces; |
45 | b9f5b594 | Panagiotis Kanavos | |
46 | b9f5b594 | Panagiotis Kanavos | namespace Pithos.Core.Agents |
47 | b9f5b594 | Panagiotis Kanavos | { |
48 | b9f5b594 | Panagiotis Kanavos | using System; |
49 | b9f5b594 | Panagiotis Kanavos | using System.Collections.Generic; |
50 | b9f5b594 | Panagiotis Kanavos | using System.Linq; |
51 | b9f5b594 | Panagiotis Kanavos | using System.Text; |
52 | b9f5b594 | Panagiotis Kanavos | |
53 | b9f5b594 | Panagiotis Kanavos | /// <summary> |
54 | b9f5b594 | Panagiotis Kanavos | /// Extension methods for collections |
55 | b9f5b594 | Panagiotis Kanavos | /// </summary> |
56 | b9f5b594 | Panagiotis Kanavos | public static class CollectionExtensions |
57 | b9f5b594 | Panagiotis Kanavos | { |
58 | b9f5b594 | Panagiotis Kanavos | /// <summary> |
59 | b9f5b594 | Panagiotis Kanavos | /// Remove the first message in a queue that matches the predicate |
60 | b9f5b594 | Panagiotis Kanavos | /// </summary> |
61 | b9f5b594 | Panagiotis Kanavos | /// <param name="predicate">The condition to match</param> |
62 | b9f5b594 | Panagiotis Kanavos | /// <remarks>Removes the first message that matches the predicate by dequeing all |
63 | b9f5b594 | Panagiotis Kanavos | /// messages and re-enqueing all except the first matching message</remarks> |
64 | b9f5b594 | Panagiotis Kanavos | public static void RemoveFirst<TMessage>(this ConcurrentQueue<TMessage> queue, Func<TMessage, bool> predicate) |
65 | b9f5b594 | Panagiotis Kanavos | { |
66 | b9f5b594 | Panagiotis Kanavos | //Can this work? Dequeue all items |
67 | b9f5b594 | Panagiotis Kanavos | //and then enqueue everything except the filtered items |
68 | b9f5b594 | Panagiotis Kanavos | |
69 | b9f5b594 | Panagiotis Kanavos | //Possible problems: |
70 | b9f5b594 | Panagiotis Kanavos | //* A matching item may be dequeued between one TryDequeue and the next |
71 | b9f5b594 | Panagiotis Kanavos | var temp = new Queue<TMessage>(); |
72 | b9f5b594 | Panagiotis Kanavos | TMessage message; |
73 | b9f5b594 | Panagiotis Kanavos | var alreadyFound = false; |
74 | b9f5b594 | Panagiotis Kanavos | while (queue.TryDequeue(out message)) |
75 | b9f5b594 | Panagiotis Kanavos | { |
76 | b9f5b594 | Panagiotis Kanavos | if (!predicate(message) || alreadyFound) |
77 | b9f5b594 | Panagiotis Kanavos | temp.Enqueue(message); |
78 | b9f5b594 | Panagiotis Kanavos | else |
79 | b9f5b594 | Panagiotis Kanavos | { |
80 | b9f5b594 | Panagiotis Kanavos | alreadyFound = true; |
81 | b9f5b594 | Panagiotis Kanavos | } |
82 | b9f5b594 | Panagiotis Kanavos | } |
83 | b9f5b594 | Panagiotis Kanavos | |
84 | b9f5b594 | Panagiotis Kanavos | queue.AddFromEnumerable(temp); |
85 | b9f5b594 | Panagiotis Kanavos | } |
86 | 759bd3c4 | Panagiotis Kanavos | |
87 | 759bd3c4 | Panagiotis Kanavos | |
88 | 759bd3c4 | Panagiotis Kanavos | public static IEnumerable<ObjectInfo> FilterBelow(this IEnumerable<ObjectInfo> infos,List<Uri> filterUris ) |
89 | 759bd3c4 | Panagiotis Kanavos | { |
90 | 759bd3c4 | Panagiotis Kanavos | if (filterUris == null) |
91 | 759bd3c4 | Panagiotis Kanavos | return infos; |
92 | 759bd3c4 | Panagiotis Kanavos | if (filterUris.Count == 0) |
93 | 759bd3c4 | Panagiotis Kanavos | return infos; |
94 | fec5da06 | Panagiotis Kanavos | //Allow all objects whose Uris start with any of the filters |
95 | 759bd3c4 | Panagiotis Kanavos | var filteredUris = from info in infos |
96 | fec5da06 | Panagiotis Kanavos | where filterUris.Any(f => info.Uri.IsAtOrBelow(f)) |
97 | fec5da06 | Panagiotis Kanavos | select info; |
98 | 759bd3c4 | Panagiotis Kanavos | return filteredUris; |
99 | 759bd3c4 | Panagiotis Kanavos | } |
100 | fec5da06 | Panagiotis Kanavos | |
101 | fec5da06 | Panagiotis Kanavos | public static IEnumerable<ObjectInfo> FilterDirectlyBelow(this IEnumerable<ObjectInfo> infos,List<Uri> filterUris ) |
102 | fec5da06 | Panagiotis Kanavos | { |
103 | fec5da06 | Panagiotis Kanavos | if (filterUris == null) |
104 | fec5da06 | Panagiotis Kanavos | return infos; |
105 | fec5da06 | Panagiotis Kanavos | if (filterUris.Count == 0) |
106 | fec5da06 | Panagiotis Kanavos | return infos; |
107 | fec5da06 | Panagiotis Kanavos | //Allow all objects whose Uris start with any of the filters |
108 | fec5da06 | Panagiotis Kanavos | var filteredUris = from info in infos |
109 | fec5da06 | Panagiotis Kanavos | where filterUris.Any(f => info.Uri.IsAtOrDirectlyBelow(f)) |
110 | fec5da06 | Panagiotis Kanavos | select info; |
111 | fec5da06 | Panagiotis Kanavos | return filteredUris; |
112 | fec5da06 | Panagiotis Kanavos | } |
113 | fec5da06 | Panagiotis Kanavos | |
114 | fec5da06 | Panagiotis Kanavos | public static bool IsAtOrBelow(this Uri target,Uri root) |
115 | fec5da06 | Panagiotis Kanavos | { |
116 | fec5da06 | Panagiotis Kanavos | Contract.Requires(root != null); |
117 | fec5da06 | Panagiotis Kanavos | Contract.Requires(target != null); |
118 | fec5da06 | Panagiotis Kanavos | |
119 | fec5da06 | Panagiotis Kanavos | var targetSegments = target.Segments; |
120 | fec5da06 | Panagiotis Kanavos | var rootSegments = root.Segments; |
121 | fec5da06 | Panagiotis Kanavos | |
122 | fec5da06 | Panagiotis Kanavos | return InnerAtOrBelow(targetSegments, rootSegments); |
123 | fec5da06 | Panagiotis Kanavos | } |
124 | fec5da06 | Panagiotis Kanavos | |
125 | fec5da06 | Panagiotis Kanavos | private static bool InnerAtOrBelow(string[] targetSegments, string[] rootSegments) |
126 | fec5da06 | Panagiotis Kanavos | { |
127 | fec5da06 | Panagiotis Kanavos | //If the uri is shorter than the root, no point in comparing |
128 | fec5da06 | Panagiotis Kanavos | if (targetSegments.Length < rootSegments.Length) |
129 | fec5da06 | Panagiotis Kanavos | return false; |
130 | fec5da06 | Panagiotis Kanavos | //If the uri is below the root, it should match the root's segments one by one |
131 | fec5da06 | Panagiotis Kanavos | //If there is any root segment that doesn't match its corresponding target segment, |
132 | fec5da06 | Panagiotis Kanavos | //the target is not below the root |
133 | fec5da06 | Panagiotis Kanavos | var mismatch = rootSegments |
134 | fec5da06 | Panagiotis Kanavos | .Where((t, i) => !String.Equals(targetSegments[i], t)) |
135 | fec5da06 | Panagiotis Kanavos | .Any(); |
136 | fec5da06 | Panagiotis Kanavos | return !mismatch; |
137 | fec5da06 | Panagiotis Kanavos | } |
138 | fec5da06 | Panagiotis Kanavos | |
139 | fec5da06 | Panagiotis Kanavos | |
140 | fec5da06 | Panagiotis Kanavos | public static bool IsAtOrDirectlyBelow(this Uri target,Uri root) |
141 | fec5da06 | Panagiotis Kanavos | { |
142 | fec5da06 | Panagiotis Kanavos | Contract.Requires(root!=null); |
143 | fec5da06 | Panagiotis Kanavos | Contract.Requires(target!=null); |
144 | fec5da06 | Panagiotis Kanavos | |
145 | fec5da06 | Panagiotis Kanavos | return |
146 | fec5da06 | Panagiotis Kanavos | //If the target is directly below the root, it will have exactly |
147 | fec5da06 | Panagiotis Kanavos | //one segment more than the root |
148 | fec5da06 | Panagiotis Kanavos | target.Segments.Length == root.Segments.Length + 1 |
149 | fec5da06 | Panagiotis Kanavos | //Ensure that the candidate target is indeed below the root |
150 | fec5da06 | Panagiotis Kanavos | && target.IsAtOrBelow(root); |
151 | fec5da06 | Panagiotis Kanavos | } |
152 | fec5da06 | Panagiotis Kanavos | |
153 | fec5da06 | Panagiotis Kanavos | public static bool IsAtOrBelow(this string targetPath, string rootPath) |
154 | fec5da06 | Panagiotis Kanavos | { |
155 | fec5da06 | Panagiotis Kanavos | Contract.Requires(!String.IsNullOrWhiteSpace(targetPath)); |
156 | fec5da06 | Panagiotis Kanavos | Contract.Requires(!String.IsNullOrWhiteSpace(rootPath)); |
157 | fec5da06 | Panagiotis Kanavos | |
158 | fec5da06 | Panagiotis Kanavos | var targetSegments = targetPath.Split('\\'); |
159 | fec5da06 | Panagiotis Kanavos | var rootSegments = rootPath.Split('\\'); |
160 | fec5da06 | Panagiotis Kanavos | |
161 | fec5da06 | Panagiotis Kanavos | return InnerAtOrBelow(targetSegments, rootSegments); |
162 | fec5da06 | Panagiotis Kanavos | } |
163 | fec5da06 | Panagiotis Kanavos | |
164 | fec5da06 | Panagiotis Kanavos | public static bool IsAtOrDirectlyBelow(this string targetPath, string rootPath) |
165 | fec5da06 | Panagiotis Kanavos | { |
166 | fec5da06 | Panagiotis Kanavos | Contract.Requires(!String.IsNullOrWhiteSpace(targetPath)); |
167 | fec5da06 | Panagiotis Kanavos | Contract.Requires(!String.IsNullOrWhiteSpace(rootPath)); |
168 | fec5da06 | Panagiotis Kanavos | |
169 | fec5da06 | Panagiotis Kanavos | var targetSegments = targetPath.Split('\\'); |
170 | fec5da06 | Panagiotis Kanavos | var rootSegments = rootPath.Split('\\'); |
171 | fec5da06 | Panagiotis Kanavos | |
172 | fec5da06 | Panagiotis Kanavos | return |
173 | fec5da06 | Panagiotis Kanavos | //If the target is directly below the root, it will have exactly |
174 | fec5da06 | Panagiotis Kanavos | //one segment more than the root |
175 | fec5da06 | Panagiotis Kanavos | targetSegments.Length == rootSegments.Length + 1 |
176 | fec5da06 | Panagiotis Kanavos | //Ensure that the candidate target is indeed below the root |
177 | fec5da06 | Panagiotis Kanavos | && InnerAtOrBelow(targetSegments, rootSegments); |
178 | fec5da06 | Panagiotis Kanavos | } |
179 | b9f5b594 | Panagiotis Kanavos | } |
180 | b9f5b594 | Panagiotis Kanavos | } |