This file is indexed.

/usr/include/rdkit/GraphMol/FMCS/SubstructureCache.h is in librdkit-dev 201503-3.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
//
//  Copyright (C) 2014 Novartis Institutes for BioMedical Research
//
//   @@ All Rights Reserved @@
//  This file is part of the RDKit.
//  The contents are covered by the terms of the BSD license
//  which is included in the file license.txt, found at the root
//  of the RDKit source tree.
//
#pragma once
#include <list>
#include <vector>
#include <string>
#include <stdexcept>
#include "../RDKitBase.h"
//#include "../Fingerprints/MorganFingerprints.h"
#include "Graph.h"
#include "Seed.h"
#include "DebugTrace.h" // algorithm filter definitions

namespace RDKit {
    namespace FMCS {
        class SubstructureCache {
        public:

#pragma pack(push,1)
            struct KeyNumericMetrics {
                typedef unsigned long long TValue;
                TValue Value;
            public:
                KeyNumericMetrics() : Value(0) {}
            };
#pragma pack(pop)

            struct HashKey {
                KeyNumericMetrics   NumericMetrics;
            public:
                void computeKey (const Seed& seed, const std::vector<unsigned>& queryAtomLabels, const std::vector<unsigned>& queryBondLabels) {
                    computeMorganCodeHash(seed, queryAtomLabels, queryBondLabels);
                }
            private:
                void computeMorganCodeHash(const Seed& seed
                                           , const std::vector<unsigned>& queryAtomLabels, const std::vector<unsigned>& queryBondLabels) {
                    size_t nv = seed.getNumAtoms();
                    size_t ne = seed.getNumBonds();
                    std::vector<unsigned long> currCodes(nv);
                    std::vector<unsigned long> prevCodes(nv);
                    size_t nIterations = seed.getNumBonds();
                    if (nIterations > 5)
                        nIterations = 5;

                    for(unsigned seedAtomIdx = 0; seedAtomIdx < seed.getNumAtoms(); seedAtomIdx++)
                        currCodes[seedAtomIdx] = queryAtomLabels[seed.MoleculeFragment.AtomsIdx[seedAtomIdx]];

                    for (size_t iter = 0; iter < nIterations; iter++) {
                        for (size_t i = 0; i < nv; i++)
                            prevCodes[i] = currCodes[i];

                        for (size_t seedBondIdx= 0; seedBondIdx< ne; seedBondIdx++) {
                            const Bond* bond = seed.MoleculeFragment.Bonds[seedBondIdx];
                            unsigned order =  queryBondLabels[seed.MoleculeFragment.BondsIdx[seedBondIdx]];
                            unsigned atom1= seed.MoleculeFragment.SeedAtomIdxMap.find(bond->getBeginAtomIdx())->second;
                            unsigned atom2= seed.MoleculeFragment.SeedAtomIdxMap.find(bond->getEndAtomIdx  ())->second;
                            unsigned v1 = prevCodes[atom1];
                            unsigned v2 = prevCodes[atom2];

                            currCodes[atom1] += v2*v2 + (v2 + 23) * (order + 1721);
                            currCodes[atom2] += v1*v1 + (v1 + 23) * (order + 1721);
                        }
                    }

                    KeyNumericMetrics::TValue result = 0;
                    for(unsigned seedAtomIdx = 0; seedAtomIdx < nv; seedAtomIdx++) {
                        unsigned long code = currCodes[seedAtomIdx];
                        result += code * (code + 6849) + 29;
                    }

                    NumericMetrics.Value = result;

                }

//not implemented yet:
                /*
                            void computeFingerprint(const Seed& seed)
                            {
                            unsigned int radius = seed.getNumBonds();
                            if (radius > 5)
                                radius = 5;
                            ExplicitBitVect *mf = RDKit::MorganFingerprints::getFingerprintAsBitVect(seed.GraphTopology, radius);   //SLOW !!!
                            // ...
                            delete mf;
                                NumericMetrics.Field.hasFingerprint = 1;
                            }
                */
            };

            typedef HashKey                TKey;
            typedef std::list<FMCS::Graph> TIndexEntry; // hash-key is not unique key
        private:
            std::vector<TIndexEntry>                    ValueStorage;
            std::map<KeyNumericMetrics::TValue, size_t> NumericIndex;  // TIndexEntry
        public:
            // returns computed key, and pointer to index entry with a set of subgraphs corresponding to the key if found.
            // then caller must find exactly matched subgraph in the result set with own search algorithm,
            // including a resolving of collisions of hash key
            TIndexEntry* find(const Seed& seed, const std::vector<unsigned>& queryAtomLabels
                              , const std::vector<unsigned>& queryBondLabels
                              , TKey& key) { // compute key and find entry
                key.computeKey(seed, queryAtomLabels, queryBondLabels);
                std::map<KeyNumericMetrics::TValue, size_t>::const_iterator
                entryit = NumericIndex.find(key.NumericMetrics.Value);
                if(NumericIndex.end() != entryit)
                    return & ValueStorage[entryit->second];
                return NULL;    // not found
            }

            //if find() did not found any entry for this key of seed a new entry will be created
            void add(const Seed& seed, TKey& key, TIndexEntry* entry) { // "compute" value and store it in NEW entry if not found
                if(!entry) {
                    try {
                        ValueStorage.push_back(TIndexEntry());
                    } catch(...) {
                        return;   // not enought memory room to add the item, but it's just a cache
                    }
                    entry = &ValueStorage.back();
                }
                entry->push_back(seed.Topology);

                if(!NumericIndex.insert( std::pair<KeyNumericMetrics::TValue, size_t>(key.NumericMetrics.Value, ValueStorage.size()-1) ).second)
                    return; // not enought memory room to add the item, but it is just cache
            }


            size_t keyssize() const { // for statistics only
                return ValueStorage.size();
            }

            size_t fullsize() const { // for statistics only
                size_t n = 0;
                for(std::vector<TIndexEntry>::const_iterator e = ValueStorage.begin(); e != ValueStorage.end(); e++)
                    n += e->size();
                return n;
            }
        };
    }
}