| /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ |
| /* |
| * Copyright (c) 2014-2018, The University of Memphis |
| * |
| * This file is part of PSync. |
| * See AUTHORS.md for complete list of PSync authors and contributors. |
| * |
| * PSync is free software: you can redistribute it and/or modify it under the terms |
| * of the GNU General Public License as published by the Free Software Foundation, |
| * either version 3 of the License, or (at your option) any later version. |
| * |
| * PSync is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; |
| * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR |
| * PURPOSE. See the GNU General Public License for more details. |
| * |
| * You should have received a copy of the GNU General Public License along with |
| * PSync, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>. |
| * |
| |
| * This file incorporates work covered by the following copyright and |
| * permission notice: |
| |
| * The MIT License (MIT) |
| |
| * Copyright (c) 2014 Gavin Andresen |
| |
| * Permission is hereby granted, free of charge, to any person obtaining a copy |
| * of this software and associated documentation files (the "Software"), to deal |
| * in the Software without restriction, including without limitation the rights |
| * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| * copies of the Software, and to permit persons to whom the Software is |
| * furnished to do so, subject to the following conditions: |
| |
| * The above copyright notice and this permission notice shall be included in all |
| * copies or substantial portions of the Software. |
| |
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
| * SOFTWARE. |
| */ |
| |
| #ifndef PSYNC_IBLT_HPP |
| #define PSYNC_IBLT_HPP |
| |
| #include <ndn-cxx/name.hpp> |
| |
| #include <inttypes.h> |
| #include <set> |
| #include <vector> |
| #include <string> |
| |
| namespace psync { |
| |
| class HashTableEntry |
| { |
| public: |
| int32_t count; |
| uint32_t keySum; |
| uint32_t keyCheck; |
| |
| bool |
| isPure() const; |
| |
| bool |
| isEmpty() const; |
| }; |
| |
| extern const size_t N_HASH; |
| extern const size_t N_HASHCHECK; |
| |
| /** |
| * @brief Invertible Bloom Lookup Table (Invertible Bloom Filter) |
| * |
| * Used by Partial Sync (PartialProducer) and Full Sync (Full Producer) |
| */ |
| class IBLT |
| { |
| public: |
| class Error : public std::runtime_error |
| { |
| public: |
| using std::runtime_error::runtime_error; |
| }; |
| |
| /** |
| * @brief constructor |
| * |
| * @param expectedNumEntries the expected number of entries in the IBLT |
| */ |
| explicit IBLT(size_t expectedNumEntries); |
| |
| /** |
| * @brief Populate the hash table using the vector representation of IBLT |
| * |
| * @param ibltName the Component representation of IBLT |
| * @throws Error if size of values is not compatible with this IBF |
| */ |
| void |
| initialize(const ndn::name::Component& ibltName); |
| |
| void |
| insert(uint32_t key); |
| |
| void |
| erase(uint32_t key); |
| |
| /** |
| * @brief List all the entries in the IBLT |
| * |
| * This is called on a difference of two IBLTs: ownIBLT - rcvdIBLT |
| * Entries listed in positive are in ownIBLT but not in rcvdIBLT |
| * Entries listed in negative are in rcvdIBLT but not in ownIBLT |
| * |
| * @param positive |
| * @param negative |
| * @return true if decoding is complete successfully |
| */ |
| bool |
| listEntries(std::set<uint32_t>& positive, std::set<uint32_t>& negative) const; |
| |
| IBLT |
| operator-(const IBLT& other) const; |
| |
| std::vector<HashTableEntry> |
| getHashTable() const |
| { |
| return m_hashTable; |
| } |
| |
| /** |
| * @brief Appends self to name |
| * |
| * Encodes our hash table from uint32_t vector to uint8_t vector |
| * We create a uin8_t vector 12 times the size of uint32_t vector |
| * We put the first count in first 4 cells, keySum in next 4, and keyCheck in next 4. |
| * Repeat for all the other cells of the hash table. |
| * Then we append this uint8_t vector to the name. |
| * |
| * @param name |
| */ |
| void |
| appendToName(ndn::Name& name) const; |
| |
| /** |
| * @brief Extracts IBLT from name component |
| * |
| * Converts the name into a uint8_t vector which is then decoded to a |
| * a uint32_t vector. |
| * |
| * @param ibltName IBLT represented as a Name Component |
| * @return a uint32_t vector representing the hash table of the IBLT |
| */ |
| std::vector<uint32_t> |
| extractValueFromName(const ndn::name::Component& ibltName) const; |
| |
| private: |
| void |
| update(int plusOrMinus, uint32_t key); |
| |
| private: |
| std::vector<HashTableEntry> m_hashTable; |
| static const int INSERT = 1; |
| static const int ERASE = -1; |
| }; |
| |
| bool |
| operator==(const IBLT& iblt1, const IBLT& iblt2); |
| |
| bool |
| operator!=(const IBLT& iblt1, const IBLT& iblt2); |
| |
| std::ostream& |
| operator<<(std::ostream& out, const IBLT& iblt); |
| |
| } // namespace psync |
| |
| #endif // PSYNC_IBLT_HPP |