GUI: trie utility operations, and test code.
Change-Id: I7f41d84b880a8e2075cf1c983be9a4a2def01856
Showing
3 changed files
with
265 additions
and
22 deletions
web/gui/src/main/webapp/_sdh/trie-test.html
0 → 100644
1 | +<!DOCTYPE html> | ||
2 | +<!-- | ||
3 | + ~ Copyright 2016 Open Networking Laboratory | ||
4 | + ~ | ||
5 | + ~ Licensed under the Apache License, Version 2.0 (the "License"); | ||
6 | + ~ you may not use this file except in compliance with the License. | ||
7 | + ~ You may obtain a copy of the License at | ||
8 | + ~ | ||
9 | + ~ http://www.apache.org/licenses/LICENSE-2.0 | ||
10 | + ~ | ||
11 | + ~ Unless required by applicable law or agreed to in writing, software | ||
12 | + ~ distributed under the License is distributed on an "AS IS" BASIS, | ||
13 | + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
14 | + ~ See the License for the specific language governing permissions and | ||
15 | + ~ limitations under the License. | ||
16 | + --> | ||
17 | + | ||
18 | +<!-- | ||
19 | + ONOS -- Sample use of trie functions in fn.js | ||
20 | + --> | ||
21 | + | ||
22 | +<html> | ||
23 | +<head lang="en"> | ||
24 | + <meta charset="UTF-8"> | ||
25 | + <title>Test Trie Functions</title> | ||
26 | + | ||
27 | + <script type="text/javascript" src="../tp/angular.js"></script> | ||
28 | + <script type="text/javascript" src="../tp/angular-route.js"></script> | ||
29 | + | ||
30 | + <script type="text/javascript" src="../tp/d3.js"></script> | ||
31 | + | ||
32 | + <script type="text/javascript" src="../app/fw/util/util.js"></script> | ||
33 | + <script type="text/javascript" src="../app/fw/util/fn.js"></script> | ||
34 | + | ||
35 | + <script type="text/javascript" src="trie-test.js"></script> | ||
36 | + | ||
37 | + <link rel="stylesheet" href="../app/common.css"> | ||
38 | + | ||
39 | + <style> | ||
40 | + html, | ||
41 | + body { | ||
42 | + background-color: #ddf; | ||
43 | + font-family: Arial, Helvetica, sans-serif; | ||
44 | + font-size: 9pt; | ||
45 | + } | ||
46 | + | ||
47 | + h2 { | ||
48 | + color: darkred; | ||
49 | + } | ||
50 | + | ||
51 | + #output div { | ||
52 | + font-family: monospace; | ||
53 | + white-space: pre; | ||
54 | + } | ||
55 | + </style> | ||
56 | + | ||
57 | +</head> | ||
58 | + | ||
59 | +<!-- outline for using a controller in Angular --> | ||
60 | +<body class="light" ng-app="trie" ng-controller="OvTrieTest as ctrl"> | ||
61 | + <h2>Testing the Trie Functions</h2> | ||
62 | + <div id="output"></div> | ||
63 | +</body> | ||
64 | +</html> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
web/gui/src/main/webapp/_sdh/trie-test.js
0 → 100644
1 | +/* | ||
2 | + * Copyright 2016 Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +/* | ||
18 | + ONOS GUI -- Test code illustrating use of trie functions | ||
19 | + */ | ||
20 | + | ||
21 | +(function () { | ||
22 | + 'use strict'; | ||
23 | + | ||
24 | + // injected refs | ||
25 | + var $log, fs; | ||
26 | + | ||
27 | + // internal state | ||
28 | + var out, | ||
29 | + trie = {}, | ||
30 | + counter = 5000; | ||
31 | + | ||
32 | + function write(string) { | ||
33 | + out.append('div').text(string); | ||
34 | + } | ||
35 | + | ||
36 | + function lookup(word) { | ||
37 | + var result = fs.trieLookup(trie, word), | ||
38 | + f = fs.isF(result), | ||
39 | + show = f ? '{function}' : result; | ||
40 | + | ||
41 | + | ||
42 | + write('------> ' + word + ' ==> ' + show); | ||
43 | + | ||
44 | + f && f(); | ||
45 | + } | ||
46 | + | ||
47 | + function add(word, data) { | ||
48 | + var result = fs.addToTrie(trie, word, data); | ||
49 | + write(' ADD> ' + word + ' [' + data + '] ==> ' + result); | ||
50 | + } | ||
51 | + | ||
52 | + function remove(word) { | ||
53 | + var result = fs.removeFromTrie(trie, word); | ||
54 | + write('REMOVE> ' + word + ' ==> ' + result); | ||
55 | + } | ||
56 | + | ||
57 | + function func1() { | ||
58 | + counter++; | ||
59 | + write('** function call ** ' + counter); | ||
60 | + } | ||
61 | + | ||
62 | + function func2() { | ||
63 | + counter += 11; | ||
64 | + write('** alternate call ** ' + counter); | ||
65 | + } | ||
66 | + | ||
67 | + function runTests() { | ||
68 | + lookup('cat'); | ||
69 | + | ||
70 | + add('cat', 101); | ||
71 | + | ||
72 | + lookup('ca'); | ||
73 | + lookup('cat'); | ||
74 | + lookup('cats'); | ||
75 | + | ||
76 | + add('cab', 103); | ||
77 | + add('cog', 105); | ||
78 | + | ||
79 | + lookup('cut'); | ||
80 | + lookup('cab'); | ||
81 | + | ||
82 | + remove('cab'); | ||
83 | + | ||
84 | + lookup('cab'); | ||
85 | + lookup('cat'); | ||
86 | + | ||
87 | + add('fun', func1); | ||
88 | + | ||
89 | + lookup('fun'); | ||
90 | + lookup('fun'); | ||
91 | + lookup('fun'); | ||
92 | + lookup('cat'); | ||
93 | + lookup('fun'); | ||
94 | + | ||
95 | + add('fun', func2); | ||
96 | + | ||
97 | + lookup('fun'); | ||
98 | + lookup('fun'); | ||
99 | + lookup('fun'); | ||
100 | + | ||
101 | + remove('fun'); | ||
102 | + | ||
103 | + lookup('fun'); | ||
104 | + } | ||
105 | + | ||
106 | + angular.module('trie', ['onosUtil']) | ||
107 | + .controller('OvTrieTest', ['$log', 'FnService', | ||
108 | + | ||
109 | + function (_$log_, _fs_) { | ||
110 | + $log = _$log_; | ||
111 | + fs = _fs_; | ||
112 | + out = d3.select('#output'); | ||
113 | + | ||
114 | + runTests(); | ||
115 | + }]); | ||
116 | +}()); |
... | @@ -287,11 +287,16 @@ | ... | @@ -287,11 +287,16 @@ |
287 | } | 287 | } |
288 | } | 288 | } |
289 | 289 | ||
290 | - // generate a trie structure from the given array of strings | 290 | + // trie operation |
291 | - // if ignoreCase is true, all words are converted to uppercase first | 291 | + function _trieOp(op, trie, word, data) { |
292 | - // note: each letter in each string must be valid as an object property key | 292 | + var p = trie, |
293 | - function createTrie(words, ignoreCase) { | 293 | + w = word.toUpperCase(), |
294 | - var trie = {}; | 294 | + s = w.split(''), |
295 | + c = { p: p, s: s }, | ||
296 | + t = [], | ||
297 | + x = 0, | ||
298 | + f1 = op === '+' ? add : probe, | ||
299 | + f2 = op === '+' ? insert : remove; | ||
295 | 300 | ||
296 | function add(c) { | 301 | function add(c) { |
297 | var q = c.s.shift(), | 302 | var q = c.s.shift(), |
... | @@ -300,31 +305,87 @@ | ... | @@ -300,31 +305,87 @@ |
300 | if (!np) { | 305 | if (!np) { |
301 | c.p[q] = {}; | 306 | c.p[q] = {}; |
302 | np = c.p[q]; | 307 | np = c.p[q]; |
308 | + x = 1; | ||
303 | } | 309 | } |
310 | + return { p: np, s: c.s } | ||
311 | + } | ||
304 | 312 | ||
305 | - return { | 313 | + function probe(c) { |
306 | - p: np, | 314 | + var q = c.s.shift(), |
307 | - s: c.s | 315 | + k = Object.keys(c.p).length, |
316 | + np = c.p[q]; | ||
317 | + | ||
318 | + t.push({ q:q, k:k, p:c.p }); | ||
319 | + if (!np) { | ||
320 | + t = []; | ||
321 | + return { s: [] }; | ||
308 | } | 322 | } |
323 | + return { p: np, s: c.s } | ||
309 | } | 324 | } |
310 | 325 | ||
311 | - words.forEach(function (word) { | 326 | + function insert() { |
312 | - var p = trie, | 327 | + c.p._data = data; |
313 | - w = ignoreCase ? word.toUpperCase() : word, | 328 | + return x ? 'added' : 'updated'; |
314 | - s = w.split(''), | 329 | + } |
315 | - c = { | 330 | + |
316 | - p: p, | 331 | + function remove() { |
317 | - s: s | 332 | + if (t.length) { |
318 | - }; | 333 | + t = t.reverse(); |
319 | - | 334 | + while (t.length) { |
320 | - while (c.s.length) { | 335 | + c = t.shift(); |
321 | - c = add(c); | 336 | + delete c.p[c.q]; |
337 | + if (c.k > 1) { | ||
338 | + t = []; | ||
339 | + } | ||
340 | + } | ||
341 | + return 'removed'; | ||
322 | } | 342 | } |
323 | - }); | 343 | + return 'absent'; |
344 | + } | ||
324 | 345 | ||
325 | - return trie; | 346 | + while (c.s.length) { |
347 | + c = f1(c); | ||
348 | + } | ||
349 | + return f2(); | ||
326 | } | 350 | } |
327 | 351 | ||
352 | + // add word to trie (word will be converted to uppercase) | ||
353 | + // data associated with the word | ||
354 | + // returns 'added' or 'updated' | ||
355 | + function addToTrie(trie, word, data) { | ||
356 | + return _trieOp('+', trie, word, data); | ||
357 | + } | ||
358 | + | ||
359 | + // remove word from trie (word will be converted to uppercase) | ||
360 | + // returns 'removed' or 'absent' | ||
361 | + function removeFromTrie(trie, word) { | ||
362 | + return _trieOp('-', trie, word); | ||
363 | + } | ||
364 | + | ||
365 | + // lookup word (converted to uppercase) in trie | ||
366 | + // returns: | ||
367 | + // undefined if the word is not in the trie | ||
368 | + // -1 for a partial match (word is a prefix to an existing word) | ||
369 | + // data for the word for an exact match | ||
370 | + function trieLookup(trie, word) { | ||
371 | + var s = word.toUpperCase().split(''), | ||
372 | + p = trie, | ||
373 | + n; | ||
374 | + | ||
375 | + while (s.length) { | ||
376 | + n = s.shift(); | ||
377 | + p = p[n]; | ||
378 | + if (!p) { | ||
379 | + return undefined; | ||
380 | + } | ||
381 | + } | ||
382 | + if (p._data) { | ||
383 | + return p._data; | ||
384 | + } | ||
385 | + return -1; | ||
386 | + } | ||
387 | + | ||
388 | + | ||
328 | angular.module('onosUtil') | 389 | angular.module('onosUtil') |
329 | .factory('FnService', | 390 | .factory('FnService', |
330 | ['$window', '$location', '$log', function (_$window_, $loc, _$log_) { | 391 | ['$window', '$location', '$log', function (_$window_, $loc, _$log_) { |
... | @@ -360,7 +421,9 @@ | ... | @@ -360,7 +421,9 @@ |
360 | noPxStyle: noPxStyle, | 421 | noPxStyle: noPxStyle, |
361 | endsWith: endsWith, | 422 | endsWith: endsWith, |
362 | parseBitRate: parseBitRate, | 423 | parseBitRate: parseBitRate, |
363 | - createTrie: createTrie | 424 | + addToTrie: addToTrie, |
425 | + removeFromTrie: removeFromTrie, | ||
426 | + trieLookup: trieLookup | ||
364 | }; | 427 | }; |
365 | }]); | 428 | }]); |
366 | 429 | ... | ... |
-
Please register or login to post a comment