GUI: trie utility operations, and test code.
Change-Id: I7f41d84b880a8e2075cf1c983be9a4a2def01856
Showing
3 changed files
with
263 additions
and
20 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,30 +305,86 @@ | ... | @@ -300,30 +305,86 @@ |
| 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; | ||
| 309 | + } | ||
| 310 | + return { p: np, s: c.s } | ||
| 303 | } | 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(); |
| 334 | + while (t.length) { | ||
| 335 | + c = t.shift(); | ||
| 336 | + delete c.p[c.q]; | ||
| 337 | + if (c.k > 1) { | ||
| 338 | + t = []; | ||
| 339 | + } | ||
| 340 | + } | ||
| 341 | + return 'removed'; | ||
| 342 | + } | ||
| 343 | + return 'absent'; | ||
| 344 | + } | ||
| 319 | 345 | ||
| 320 | while (c.s.length) { | 346 | while (c.s.length) { |
| 321 | - c = add(c); | 347 | + c = f1(c); |
| 322 | } | 348 | } |
| 323 | - }); | 349 | + return f2(); |
| 350 | + } | ||
| 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; | ||
| 324 | 374 | ||
| 325 | - return trie; | 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; | ||
| 326 | } | 384 | } |
| 385 | + return -1; | ||
| 386 | + } | ||
| 387 | + | ||
| 327 | 388 | ||
| 328 | angular.module('onosUtil') | 389 | angular.module('onosUtil') |
| 329 | .factory('FnService', | 390 | .factory('FnService', |
| ... | @@ -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