Example #1
0
 public void Dispose()
 {
     _revWalk.Dispose();
     COMPLETE.Dispose();
     IN_WORK_QUEUE.Dispose();
     LOCALLY_SEEN.Dispose();
     _objectDigest.Dispose();
 }
Example #2
0
        /// <summary>
        /// Produces a hash for the paths of adjacent bnodes for a bnode,
        /// incorporating all information about its subgraph of bnodes.
        /// </summary>
        /// <remarks>
        /// Produces a hash for the paths of adjacent bnodes for a bnode,
        /// incorporating all information about its subgraph of bnodes. This method
        /// will recursively pick adjacent bnode permutations that produce the
        /// lexicographically-least 'path' serializations.
        /// </remarks>
        /// <param name="id">the ID of the bnode to hash paths for.</param>
        /// <param name="bnodes">the map of bnode quads.</param>
        /// <param name="namer">the canonical bnode namer.</param>
        /// <param name="pathNamer">the namer used to assign names to adjacent bnodes.</param>
        /// <param name="callback">(err, result) called once the operation completes.</param>
        private static NormalizeUtils.HashResult HashPaths(string id, IDictionary <string, IDictionary <string, object> > bnodes, UniqueNamer namer, UniqueNamer pathNamer)
        {
#if !PORTABLE
            MessageDigest md = null;

            try
            {
                // create SHA-1 digest
                md = MessageDigest.GetInstance("SHA-1");
                JObject                 groups = new JObject();
                IList <string>          groupHashes;
                IList <RDFDataset.Quad> quads = (IList <RDFDataset.Quad>)bnodes[id]["quads"];
                for (int hpi = 0; ; hpi++)
                {
                    if (hpi == quads.Count)
                    {
                        // done , hash groups
                        groupHashes = new List <string>(groups.GetKeys());
                        ((List <string>)groupHashes).Sort(StringComparer.CurrentCultureIgnoreCase);
                        for (int hgi = 0; ; hgi++)
                        {
                            if (hgi == groupHashes.Count)
                            {
                                NormalizeUtils.HashResult res = new NormalizeUtils.HashResult();
                                res.hash      = EncodeHex(md.Digest());
                                res.pathNamer = pathNamer;
                                return(res);
                            }
                            // digest group hash
                            string groupHash = groupHashes[hgi];
                            md.Update(JsonLD.JavaCompat.GetBytesForString(groupHash, "UTF-8"));
                            // choose a path and namer from the permutations
                            string      chosenPath  = null;
                            UniqueNamer chosenNamer = null;
                            NormalizeUtils.Permutator permutator = new NormalizeUtils.Permutator((JArray)groups[groupHash]);
                            while (true)
                            {
                                bool        contPermutation = false;
                                bool        breakOut        = false;
                                JArray      permutation     = permutator.Next();
                                UniqueNamer pathNamerCopy   = pathNamer.Clone();
                                // build adjacent path
                                string path    = string.Empty;
                                JArray recurse = new JArray();
                                foreach (string bnode in permutation)
                                {
                                    // use canonical name if available
                                    if (namer.IsNamed(bnode))
                                    {
                                        path += namer.GetName(bnode);
                                    }
                                    else
                                    {
                                        // recurse if bnode isn't named in the path
                                        // yet
                                        if (!pathNamerCopy.IsNamed(bnode))
                                        {
                                            recurse.Add(bnode);
                                        }
                                        path += pathNamerCopy.GetName(bnode);
                                    }
                                    // skip permutation if path is already >= chosen
                                    // path
                                    if (chosenPath != null && path.Length >= chosenPath.Length && string.CompareOrdinal
                                            (path, chosenPath) > 0)
                                    {
                                        // return nextPermutation(true);
                                        if (permutator.HasNext())
                                        {
                                            contPermutation = true;
                                        }
                                        else
                                        {
                                            // digest chosen path and update namer
                                            md.Update(JsonLD.JavaCompat.GetBytesForString(chosenPath, "UTF-8"));
                                            pathNamer = chosenNamer;
                                            // hash the nextGroup
                                            breakOut = true;
                                        }
                                        break;
                                    }
                                }
                                // if we should do the next permutation
                                if (contPermutation)
                                {
                                    continue;
                                }
                                // if we should stop processing this group
                                if (breakOut)
                                {
                                    break;
                                }
                                // does the next recursion
                                for (int nrn = 0; ; nrn++)
                                {
                                    if (nrn == recurse.Count)
                                    {
                                        // return nextPermutation(false);
                                        if (chosenPath == null || string.CompareOrdinal(path, chosenPath) < 0)
                                        {
                                            chosenPath  = path;
                                            chosenNamer = pathNamerCopy;
                                        }
                                        if (!permutator.HasNext())
                                        {
                                            // digest chosen path and update namer
                                            md.Update(JsonLD.JavaCompat.GetBytesForString(chosenPath, "UTF-8"));
                                            pathNamer = chosenNamer;
                                            // hash the nextGroup
                                            breakOut = true;
                                        }
                                        break;
                                    }
                                    // do recursion
                                    string bnode_1 = (string)recurse[nrn];
                                    NormalizeUtils.HashResult result = HashPaths(bnode_1, bnodes, namer, pathNamerCopy);
                                    path         += pathNamerCopy.GetName(bnode_1) + "<" + result.hash + ">";
                                    pathNamerCopy = result.pathNamer;
                                    // skip permutation if path is already >= chosen
                                    // path
                                    if (chosenPath != null && path.Length >= chosenPath.Length && string.CompareOrdinal
                                            (path, chosenPath) > 0)
                                    {
                                        // return nextPermutation(true);
                                        if (!permutator.HasNext())
                                        {
                                            // digest chosen path and update namer
                                            md.Update(JsonLD.JavaCompat.GetBytesForString(chosenPath, "UTF-8"));
                                            pathNamer = chosenNamer;
                                            // hash the nextGroup
                                            breakOut = true;
                                        }
                                        break;
                                    }
                                }
                                // do next recursion
                                // if we should stop processing this group
                                if (breakOut)
                                {
                                    break;
                                }
                            }
                        }
                    }
                    // get adjacent bnode
                    IDictionary <string, object> quad = (IDictionary <string, object>)quads[hpi];
                    string bnode_2 = GetAdjacentBlankNodeName((IDictionary <string, object>)quad["subject"
                                                              ], id);
                    string direction = null;
                    if (bnode_2 != null)
                    {
                        // normal property
                        direction = "p";
                    }
                    else
                    {
                        bnode_2 = GetAdjacentBlankNodeName((IDictionary <string, object>)quad["object"], id
                                                           );
                        if (bnode_2 != null)
                        {
                            // reverse property
                            direction = "r";
                        }
                    }
                    if (bnode_2 != null)
                    {
                        // get bnode name (try canonical, path, then hash)
                        string name;
                        if (namer.IsNamed(bnode_2))
                        {
                            name = namer.GetName(bnode_2);
                        }
                        else
                        {
                            if (pathNamer.IsNamed(bnode_2))
                            {
                                name = pathNamer.GetName(bnode_2);
                            }
                            else
                            {
                                name = HashQuads(bnode_2, bnodes, namer);
                            }
                        }
                        // hash direction, property, end bnode name/hash
                        using (MessageDigest md1 = MessageDigest.GetInstance("SHA-1"))
                        {
                            // String toHash = direction + (String) ((Map<String,
                            // Object>) quad.get("predicate")).get("value") + name;
                            md1.Update(JsonLD.JavaCompat.GetBytesForString(direction, "UTF-8"));
                            md1.Update(JsonLD.JavaCompat.GetBytesForString(((string)((IDictionary <string, object>)quad["predicate"])["value"]), "UTF-8"));
                            md1.Update(JsonLD.JavaCompat.GetBytesForString(name, "UTF-8"));
                            string groupHash = EncodeHex(md1.Digest());
                            if (groups.ContainsKey(groupHash))
                            {
                                ((JArray)groups[groupHash]).Add(bnode_2);
                            }
                            else
                            {
                                JArray tmp = new JArray();
                                tmp.Add(bnode_2);
                                groups[groupHash] = tmp;
                            }
                        }
                    }
                }
            }
            catch
            {
                // TODO: i don't expect that SHA-1 is even NOT going to be
                // available?
                // look into this further
                throw;
            }
            finally
            {
                md?.Dispose();
            }
#else
            throw new PlatformNotSupportedException();
#endif
        }