graph.js
author Tony Garnock-Jones <tonyg@kcbbs.gen.nz>
Mon Dec 21 23:52:38 2009 +0000 (2 months ago)
changeset 123 bc4c90cbd778
parent 530ab6886f6540
permissions -rw-r--r--
For OS X
     1 // Copyright (c) 2008 Tony Garnock-Jones <tonyg@lshift.net>
     2 // Copyright (c) 2008 LShift Ltd. <query@lshift.net>
     3 //
     4 // Permission is hereby granted, free of charge, to any person
     5 // obtaining a copy of this software and associated documentation files
     6 // (the "Software"), to deal in the Software without restriction,
     7 // including without limitation the rights to use, copy, modify, merge,
     8 // publish, distribute, sublicense, and/or sell copies of the Software,
     9 // and to permit persons to whom the Software is furnished to do so,
    10 // subject to the following conditions:
    11 //
    12 // The above copyright notice and this permission notice shall be
    13 // included in all copies or substantial portions of the Software.
    14 //
    15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
    16 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    17 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
    18 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
    19 // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
    20 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
    21 // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
    22 // SOFTWARE.
    23 
    24 Graph = {
    25     _foreach: function(arr, f) {
    26         for (var i = 0; i < arr.length; i++) {
    27             f(arr[i]);
    28         }
    29     },
    30 
    31     least_common_ancestor: function(parentsFun, leafId1, leafId2) {
    32         /* This is a pretty crude approximation. Since we're working
    33         with DAGs, rather than trees, it may not return the very very
    34         least common ancestor. */
    35 
    36         var potentialMatches = {};
    37 
    38         function augmentPotentialMatches(nodeId) {
    39             if (!potentialMatches[nodeId]) {
    40                 potentialMatches[nodeId] = nodeId;
    41                 Graph._foreach(parentsFun(nodeId), augmentPotentialMatches);
    42             }
    43         }
    44 
    45         augmentPotentialMatches(leafId2);
    46 
    47         var searchOrder = [leafId1];
    48 
    49         function queueForExamination(nodeId) {
    50             searchOrder.push(nodeId);
    51         }
    52 
    53         while (searchOrder.length) {
    54             var candidateId = searchOrder.shift();
    55             if (potentialMatches[candidateId]) {
    56                 return candidateId;
    57             } else {
    58                 Graph._foreach(parentsFun(candidateId), queueForExamination);
    59             }
    60         }
    61 
    62         return null; // no LCA found.
    63     }
    64 };