"Fossies" - the Fresh Open Source Software Archive

Member "netxms-3.8.166/src/server/core/inaddr_index.cpp" (23 Feb 2021, 5001 Bytes) of package /linux/misc/netxms-3.8.166.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "inaddr_index.cpp" see the Fossies "Dox" file reference documentation.

    1 /*
    2 ** NetXMS - Network Management System
    3 ** Copyright (C) 2003-2020 Victor Kirhenshtein
    4 **
    5 ** This program is free software; you can redistribute it and/or modify
    6 ** it under the terms of the GNU General Public License as published by
    7 ** the Free Software Foundation; either version 2 of the License, or
    8 ** (at your option) any later version.
    9 **
   10 ** This program is distributed in the hope that it will be useful,
   11 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
   12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   13 ** GNU General Public License for more details.
   14 **
   15 ** You should have received a copy of the GNU General Public License
   16 ** along with this program; if not, write to the Free Software
   17 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   18 **
   19 ** File: inaddr_index.cpp
   20 **
   21 **/
   22 
   23 #include "nxcore.h"
   24 #include <uthash.h>
   25 
   26 /**
   27  * Entry
   28  */
   29 struct InetAddressIndexEntry
   30 {
   31    UT_hash_handle hh;
   32    BYTE key[18];
   33    InetAddress addr;
   34    shared_ptr<NetObj> object;
   35 };
   36 
   37 /**
   38  * Constructor
   39  */
   40 InetAddressIndex::InetAddressIndex()
   41 {
   42    m_root = nullptr;
   43    m_lock = RWLockCreate();
   44 }
   45 
   46 /**
   47  * Destructor
   48  */
   49 InetAddressIndex::~InetAddressIndex()
   50 {
   51    InetAddressIndexEntry *entry, *tmp;
   52    HASH_ITER(hh, m_root, entry, tmp)
   53    {
   54       HASH_DEL(m_root, entry);
   55       entry->object.~shared_ptr();
   56       MemFree(entry);
   57    }
   58    RWLockDestroy(m_lock);
   59 }
   60 
   61 /**
   62  * Put object into index
   63  *
   64  * @param addr IP address
   65  * @param object object
   66  * @return true if existing object was replaced
   67  */
   68 bool InetAddressIndex::put(const InetAddress& addr, const shared_ptr<NetObj>& object)
   69 {
   70    if (!addr.isValidUnicast())
   71       return false;
   72 
   73    bool replace = true;
   74 
   75    BYTE key[18];
   76    addr.buildHashKey(key);
   77 
   78    RWLockWriteLock(m_lock);
   79 
   80    InetAddressIndexEntry *entry;
   81    HASH_FIND(hh, m_root, key, sizeof(key), entry);
   82    if (entry == nullptr)
   83    {
   84       entry = MemAllocStruct<InetAddressIndexEntry>();
   85       memcpy(entry->key, key, sizeof(key));
   86       entry->addr = addr;
   87       new(&entry->object) shared_ptr<NetObj>();
   88       HASH_ADD_KEYPTR(hh, m_root, entry->key, sizeof(key), entry);
   89       replace = false;
   90    }
   91    entry->object = object;
   92 
   93    RWLockUnlock(m_lock);
   94    return replace;
   95 }
   96 
   97 /**
   98  * Put object into index
   99  *
  100  * @param addrList IP address list
  101  * @param object object
  102  * @return true if existing object was replaced
  103  */
  104 bool InetAddressIndex::put(const InetAddressList *addrList, const shared_ptr<NetObj>& object)
  105 {
  106    bool replaced = false;
  107    for(int i = 0; i < addrList->size(); i++)
  108    {
  109       if (put(addrList->get(i), object))
  110          replaced = true;
  111    }
  112    return replaced;
  113 }
  114 
  115 /**
  116  * Remove object from index
  117  */
  118 void InetAddressIndex::remove(const InetAddress& addr)
  119 {
  120    if (!addr.isValidUnicast())
  121       return;
  122 
  123    BYTE key[18];
  124    addr.buildHashKey(key);
  125 
  126    RWLockWriteLock(m_lock);
  127 
  128    InetAddressIndexEntry *entry;
  129    HASH_FIND(hh, m_root, key, sizeof(key), entry);
  130    if (entry != NULL)
  131    {
  132       HASH_DEL(m_root, entry);
  133       entry->object.~shared_ptr();
  134       MemFree(entry);
  135    }
  136    RWLockUnlock(m_lock);
  137 }
  138 
  139 /**
  140  * Get object by IP address
  141  */
  142 shared_ptr<NetObj> InetAddressIndex::get(const InetAddress& addr) const
  143 {
  144    shared_ptr<NetObj> object;
  145 
  146    if (!addr.isValid())
  147       return object;
  148 
  149    BYTE key[18];
  150    addr.buildHashKey(key);
  151 
  152    RWLockReadLock(m_lock);
  153 
  154    InetAddressIndexEntry *entry;
  155    HASH_FIND(hh, m_root, key, sizeof(key), entry);
  156    if (entry != NULL)
  157    {
  158       object = entry->object;
  159    }
  160    RWLockUnlock(m_lock);
  161    return object;
  162 }
  163 
  164 /**
  165  * Find object using comparator
  166  */
  167 shared_ptr<NetObj> InetAddressIndex::find(bool (*comparator)(NetObj *, void *), void *context) const
  168 {
  169    shared_ptr<NetObj> object;
  170 
  171    RWLockReadLock(m_lock);
  172 
  173    InetAddressIndexEntry *entry, *tmp;
  174    HASH_ITER(hh, m_root, entry, tmp)
  175    {
  176       if (comparator(entry->object.get(), context))
  177       {
  178          object = entry->object;
  179          break;
  180       }
  181    }
  182 
  183    RWLockUnlock(m_lock);
  184    return object;
  185 }
  186 
  187 /**
  188  * Get index size
  189  */
  190 int InetAddressIndex::size() const
  191 {
  192    RWLockReadLock(m_lock);
  193    int s = HASH_COUNT(m_root);
  194    RWLockUnlock(m_lock);
  195    return s;
  196 }
  197 
  198 /**
  199  * Get all objects
  200  */
  201 SharedObjectArray<NetObj> *InetAddressIndex::getObjects(bool (*filter)(NetObj *, void *), void *context) const
  202 {
  203    SharedObjectArray<NetObj> *objects = new SharedObjectArray<NetObj>();
  204 
  205    RWLockReadLock(m_lock);
  206    InetAddressIndexEntry *entry, *tmp;
  207    HASH_ITER(hh, m_root, entry, tmp)
  208    {
  209       if ((filter == nullptr) || filter(entry->object.get(), context))
  210       {
  211          objects->add(entry->object);
  212       }
  213    }
  214    RWLockUnlock(m_lock);
  215    return objects;
  216 }
  217 
  218 /**
  219  * Execute given callback for each object
  220  */
  221 void InetAddressIndex::forEach(void (*callback)(const InetAddress& addr, NetObj *, void *), void *context) const
  222 {
  223    RWLockReadLock(m_lock);
  224    InetAddressIndexEntry *entry, *tmp;
  225    HASH_ITER(hh, m_root, entry, tmp)
  226    {
  227       callback(entry->addr, entry->object.get(), context);
  228    }
  229    RWLockUnlock(m_lock);
  230 }