Last active
August 29, 2015 14:09
-
-
Save awhit012/e6c91f25817a0037f18d to your computer and use it in GitHub Desktop.
Boyer-Moore
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# big text for timed tests | |
big_text = "The RSVP Hello message exchange was introduced in [RFC3209]. The | |
usage of RSVP Hello has been extended in [RFC3473] to support RSVP | |
Graceful Restart (GR) procedures. | |
More specifically, [RFC3473] specifies the use of the RSVP Hello | |
messages for GR procedures for Generalized MPLS (GMPLS). GMPLS | |
introduces the notion of control plane and data plane separation. In | |
other words, in GMPLS networks, the control plane information is | |
carried over a control network whose end-points are IP capable and | |
that may be physically or logically disjoint from the data bearer | |
links it controls. One of the consequences of separation of data | |
bearer links from control channels is that RSVP Hello messages are | |
not terminated on data bearer links' interfaces even if (some of) | |
those are numbered. Instead, RSVP Hello messages are terminated at | |
the control channel (IP-capable) end-points. The latter MAY be | |
identified by the value assigned to the node hosting these control | |
channels, i.e., Node-ID. Consequently, the use of RSVP Hello | |
messages for GR applications introduces a need for clarifying the | |
behavior and usage of Node-ID based Hello sessions. | |
Even in the case of packet switching capable interfaces, when link | |
failure detection is performed by some means other than RSVP Hello | |
messages (e.g., [BFD]), the use of Node-ID based Hello sessions is | |
also optimal for detection of signaling adjacency failures for | |
GMPLS-RSVP-TE and RSVP-TE when there is more than one link between a | |
pair of nodes. Similarly, when all TE links between neighbor nodes | |
are unnumbered, it is implied that the nodes will exchange Node-ID | |
based Hello messages for detection of signaling adjacency failures. | |
This document also clarifies the use of Node-ID based Hello message | |
exchanges when all or a sub-set of TE links are unnumbered. | |
2. Terminology | |
Node-ID: TE Router ID as advertised in the Router Address TLV for | |
OSPF [OSPF-TE] and Traffic Engineering Router ID TLV for ISIS | |
[ISIS-TE]. For IPv6, the Node-ID refers to the Router_IPv6_Address | |
for OSPFv3 [OSPFv3-TE] and the IPv6 TE Router_ID for IS-IS | |
[IS-ISv6-TE]. | |
Node-ID based Hello Session: A Hello session in which local and | |
remote Node-IDs are used in the source and destination fields of the | |
Hello packet, respectively. | |
Interface bounded Hello Session: A Hello session in which local and | |
remote addresses of the interface in question are used in the source | |
and destination fields of the Hello packet, respectively. | |
Ali, et al. Standards Track [Page 2] | |
RFC 4558 Node-ID Based RSVP Hello June 2006 | |
2.1. Conventions Used in This Document | |
3. Node-ID Based RSVP Hello Messages | |
A Node-ID based Hello session is established through the exchange of | |
RSVP Hello messages such that local and remote Node-IDs are | |
respectively used in the source and destination fields of Hello | |
packets. Here, for IPv4, Node-ID refers to the TE router-id as | |
defined in the Router Address TLV for OSPF [OSPF-TE] and the Traffic | |
Engineering router ID TLV for ISIS [ISIS-TE]. For IPv6, the Node-ID | |
refers to the Router_IPv6_Address for OSPFv3 [OSPFv3-TE] and the IPv6 | |
TE Router_ID for IS-IS [IS-ISv6-TE]. This section formalizes a | |
procedure for establishing Node-ID based Hello sessions. | |
If a node wishes to establish a Node-ID based RSVP Hello session with | |
its neighbor, it sends a Hello message with its Node-ID in the source | |
IP address field of the Hello packet. Furthermore, the node also | |
puts the neighbor's Node-ID in the destination address field of the | |
IP packet. | |
When a node receives a Hello packet where the destination IP address | |
is its local Node-ID as advertised in the IGP-TE topology, the node | |
MUST use its Node-ID in replying to the Hello message. In other | |
words, nodes MUST ensure that the Node-IDs used in RSVP Hello | |
messages are those derived/contained in the IGP-TE topology. | |
Furthermore, a node can only run one Node-ID based RSVP Hello session | |
per IGP instance (i.e., per Node-ID pair) with its neighbor. | |
Even in the case of packet switching capable interfaces, when link | |
failure detection is performed by some means other than exchanging | |
RSVP Hello messages, use of Node-ID based Hello sessions is also | |
optimal in detecting signaling adjacency failures for GMPLS-RSVP-TE | |
and RSVP-TE when there is more than one link between a pair of nodes. | |
Similarly, if all interfaces between a pair of nodes are unnumbered, | |
the optimal way to use RSVP to detect signaling adjacency failure is | |
to run Node-ID based Hello sessions. Furthermore, in the case of an | |
optical network with single or multiple numbered or unnumbered | |
control channels, use of Node-ID based Hello messages for detecting | |
signaling adjacency failure is also optimal. Therefore, when link | |
failure detection is performed by some means other than exchanging | |
RSVP Hello messages, or if all interfaces between a pair of nodes are | |
unnumbered, or in a GMPLS network with data and control plane | |
separation, a node MUST run Node-ID based Hello sessions for | |
detection of signaling adjacency failure for RSVP-TE. Nonetheless," | |
# First iteration Boyer-Moore, with no "bad character/good suffix rule". | |
def boyer_moore_search str, sub | |
str_length = str.length | |
sub_length = sub.length | |
for i in (sub_length - 1 ... str_length) | |
# if str at index i matches the last element in sub | |
if str[i] == sub[-1] | |
# set j, our sub indexer to 0 | |
j = 0 | |
# set count, our match counter to 1 | |
count = 1 | |
until j == sub_length | |
count += 1 if str[i - j] == sub[(sub_length - 1) - j] | |
return i - (sub_length - 1) if count == sub_length | |
j += 1 | |
end | |
end | |
end | |
return "not found" | |
end | |
# tests | |
puts " " | |
puts "Boyer Moore No Bad Character Test:" | |
puts " " | |
# match | |
test_str = "Hello how do you do? Good? OK great." | |
test_pattern = "great" | |
should_be = 30 | |
result = boyer_moore_search test_str, test_pattern | |
puts "Pattern at index #{result} " | |
raise "This is wrong" unless result == should_be | |
# no match | |
test_str2 = "Hello how do you do? Good? OK great." | |
test_pattern2 = "potato" | |
should_be2 = "not found" | |
result2 = boyer_moore_search test_str2, test_pattern2 | |
puts "Pattern at index #{result2} " | |
raise "This is wrong" unless result == should_be | |
#Second iteration with Bad Match Table. | |
class BM_Search | |
def initialize str, pattern | |
@str = str | |
@pattern = pattern | |
@pattern_length = pattern.length | |
@str_length = str.length | |
@distances = Hash.new | |
@index = 0 | |
bad_match_table | |
end | |
def bad_match_table | |
for i in (0...@pattern_length - 1) | |
@distances[@pattern[i]] = @pattern_length - i - 1 | |
end | |
@distances | |
end | |
def boyer_moore_search | |
until @index >= @str_length | |
# if @str at index i matches the last element in pattern | |
if @str[@index] == @pattern[-1] | |
# set j, our pattern indexer to 0 | |
j = 0 | |
# set count, our match counter to 1 | |
count = 1 | |
until j == @pattern_length | |
count += 1 if @str[@index - j] == @pattern[(@pattern_length - 1) - j] | |
return @index - (@pattern_length - 1) if count == @pattern_length | |
j += 1 | |
end | |
# if the char of the string we are looking at in not a match but IS in the pattern, | |
# find the value in @distances with the key of that char and add it to @index | |
elsif @distances[@str[@index]] != nil | |
@index += @distances[@str[@index]] | |
# if the char of the string we are looking at is not a match AND is NOT in the pattern | |
# add the pattern length to the index | |
else | |
@index += @pattern_length | |
end | |
end | |
return "not found" | |
end | |
end | |
# tests | |
puts " " | |
puts '*' * 40 | |
puts "Boyer Moore With Bad Character Test:" | |
puts " " | |
# match | |
test_str = "Hello how do you do? Good? OK great." | |
test_pattern = "great" | |
should_be = 30 | |
test = BM_Search.new test_str, test_pattern | |
result3 = test.boyer_moore_search | |
puts "Pattern at index #{result3} " | |
raise "This is wrong" unless result3 == should_be | |
# no match | |
test_str2 = "let them eat cake" | |
test_pattern2 = "potato" | |
should_be2 = "not found" | |
test2 = BM_Search.new test_str2, test_pattern2 | |
result4 = test2.boyer_moore_search | |
puts "Pattern at index #{result4} " | |
raise "This is wrong" unless result4 == should_be2 | |
# Timed Tests | |
# No Table | |
puts " " | |
puts "*" * 40 | |
puts "Timed tests:" | |
puts " " | |
puts "With no table:" | |
time_test_pattern = "RSVP-TE" | |
beginning_time = Time.now | |
boyer_moore_search big_text, time_test_pattern | |
end_time = Time.now | |
puts "Pattern at index #{boyer_moore_search big_text, time_test_pattern} " | |
puts "Time elapsed #{(end_time - beginning_time)*1000} milliseconds" | |
# With Table | |
puts " " | |
puts "With Table" | |
beginning_time2 = Time.now | |
time_test = BM_Search.new big_text, time_test_pattern | |
time_test_result = time_test.boyer_moore_search | |
end_time2 = Time.now | |
puts "Pattern at index #{time_test_result} " | |
puts "Time elapsed #{(end_time2 - beginning_time2)*1000} milliseconds" | |
puts " " |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment