blob: 45bde94056f84dcd3d7df902f1663c4b0bd16403 [file] [log] [blame]
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/*
Alexander Afanasyev3aeeaeb2014-04-22 23:34:23 -07003 * Copyright (c) 2013-2014, Regents of the University of California
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -08004 *
5 * BSD license, See the LICENSE file for more information
6 *
Alexander Afanasyev3aeeaeb2014-04-22 23:34:23 -07007 * @author Alexander Afanasyev <alexander.afanasyev@ucla.edu>
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -08008 */
9
Alexander Afanasyeve2dcdfd2014-02-07 15:53:28 -080010#include "common.hpp"
11
Alexander Afanasyev09c613f2014-01-29 00:23:58 -080012#include "exclude.hpp"
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080013
Alexander Afanasyev3aeeaeb2014-04-22 23:34:23 -070014namespace ndn {
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080015
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070016Exclude::Exclude()
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080017{
18}
19
20// example: ANY /b /d ANY /f
21//
22// ordered in map as:
23//
24// /f (false); /d (true); /b (false); / (true)
25//
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070026// lower_bound(/) -> / (true) <-- excluded (equal)
27// lower_bound(/a) -> / (true) <-- excluded (any)
28// lower_bound(/b) -> /b (false) <--- excluded (equal)
29// lower_bound(/c) -> /b (false) <--- not excluded (not equal and no ANY)
30// lower_bound(/d) -> /d (true) <- excluded
31// lower_bound(/e) -> /d (true) <- excluded
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080032bool
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070033Exclude::isExcluded(const name::Component& comp) const
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080034{
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070035 const_iterator lowerBound = m_exclude.lower_bound(comp);
36 if (lowerBound == end())
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080037 return false;
38
39 if (lowerBound->second)
40 return true;
41 else
42 return lowerBound->first == comp;
43
44 return false;
45}
46
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070047Exclude&
48Exclude::excludeOne(const name::Component& comp)
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080049{
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070050 if (!isExcluded(comp))
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080051 {
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070052 m_exclude.insert(std::make_pair(comp, false));
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080053 }
54 return *this;
55}
56
57
58// example: ANY /b0 /d0 ANY /f0
59//
60// ordered in map as:
61//
62// /f0 (false); /d0 (true); /b0 (false); / (true)
63//
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070064// lower_bound(/) -> / (true) <-- excluded (equal)
65// lower_bound(/a0) -> / (true) <-- excluded (any)
66// lower_bound(/b0) -> /b0 (false) <--- excluded (equal)
67// lower_bound(/c0) -> /b0 (false) <--- not excluded (not equal and no ANY)
68// lower_bound(/d0) -> /d0 (true) <- excluded
69// lower_bound(/e0) -> /d0 (true) <- excluded
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080070
71
72// examples with desired outcomes
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070073// excludeRange(/, /f0) -> ANY /f0
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080074// /f0 (false); / (true)
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070075// excludeRange(/, /f1) -> ANY /f1
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080076// /f1 (false); / (true)
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070077// excludeRange(/a0, /e0) -> ANY /f0
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080078// /f0 (false); / (true)
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070079// excludeRange(/a0, /e0) -> ANY /f0
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080080// /f0 (false); / (true)
81
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070082// excludeRange(/b1, /c0) -> ANY /b0 /b1 ANY /c0 /d0 ANY /f0
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080083// /f0 (false); /d0 (true); /c0 (false); /b1 (true); /b0 (false); / (true)
84
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070085Exclude&
86Exclude::excludeRange(const name::Component& from, const name::Component& to)
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080087{
Alexander Afanasyev3aeeaeb2014-04-22 23:34:23 -070088 if (from >= to) {
89 throw Error("Invalid exclude range [" +
90 from.toEscapedString() + ", " +
91 to.toEscapedString() +
92 "] (for single name exclude use Exclude::excludeOne)");
93 }
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080094
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070095 iterator newFrom = m_exclude.lower_bound(from);
Alexander Afanasyev3aeeaeb2014-04-22 23:34:23 -070096 if (newFrom == end() || !newFrom->second /*without ANY*/) {
97 std::pair<iterator, bool> fromResult = m_exclude.insert(std::make_pair(from, true));
98 newFrom = fromResult.first;
99 if (!fromResult.second) {
100 // this means that the lower bound is equal to the item itself. So, just update ANY flag
101 newFrom->second = true;
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800102 }
Alexander Afanasyev3aeeaeb2014-04-22 23:34:23 -0700103 }
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800104 // else
105 // nothing special if start of the range already exists with ANY flag set
106
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700107 iterator newTo = m_exclude.lower_bound(to); // !newTo cannot be end()
Alexander Afanasyev3aeeaeb2014-04-22 23:34:23 -0700108 if (newTo == newFrom || !newTo->second) {
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700109 std::pair<iterator, bool> toResult = m_exclude.insert(std::make_pair(to, false));
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800110 newTo = toResult.first;
111 ++ newTo;
Alexander Afanasyev3aeeaeb2014-04-22 23:34:23 -0700112 }
113 // else
114 // nothing to do really
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800115
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700116 m_exclude.erase(newTo, newFrom); // remove any intermediate node, since all of the are excluded
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800117
118 return *this;
119}
120
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700121Exclude&
122Exclude::excludeAfter(const name::Component& from)
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800123{
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700124 iterator newFrom = m_exclude.lower_bound(from);
Alexander Afanasyev3aeeaeb2014-04-22 23:34:23 -0700125 if (newFrom == end() || !newFrom->second /*without ANY*/) {
126 std::pair<iterator, bool> fromResult = m_exclude.insert(std::make_pair(from, true));
127 newFrom = fromResult.first;
128 if (!fromResult.second) {
129 // this means that the lower bound is equal to the item itself. So, just update ANY flag
130 newFrom->second = true;
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800131 }
Alexander Afanasyev3aeeaeb2014-04-22 23:34:23 -0700132 }
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800133 // else
134 // nothing special if start of the range already exists with ANY flag set
135
Alexander Afanasyev3aeeaeb2014-04-22 23:34:23 -0700136 if (newFrom != m_exclude.begin()) {
137 // remove any intermediate node, since all of the are excluded
138 m_exclude.erase(m_exclude.begin(), newFrom);
139 }
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800140
141 return *this;
142}
143
144
145std::ostream&
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700146operator<<(std::ostream& os, const Exclude& exclude)
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800147{
148 bool empty = true;
Alexander Afanasyev3aeeaeb2014-04-22 23:34:23 -0700149 for (Exclude::const_reverse_iterator i = exclude.rbegin(); i != exclude.rend(); i++) {
150 if (!i->first.empty()) {
151 if (!empty) os << ",";
152 os << i->first.toEscapedString();
153 empty = false;
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800154 }
Alexander Afanasyev3aeeaeb2014-04-22 23:34:23 -0700155 if (i->second) {
156 if (!empty) os << ",";
157 os << "*";
158 empty = false;
159 }
160 }
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800161 return os;
162}
163
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800164
Alexander Afanasyev3aeeaeb2014-04-22 23:34:23 -0700165} // namespace ndn