123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158 |
- /* Copyright (c) 2019 The Linux Foundation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- * * Neither the name of The Linux Foundation, nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
- #ifndef LOC_SKIP_LIST_H
- #define LOC_SKIP_LIST_H
- #include <stdlib.h>
- #include <list>
- #include <vector>
- #include <iostream>
- #include <algorithm>
- using namespace std;
- namespace loc_util {
- template <typename T,
- template<typename elem, typename Allocator = std::allocator<elem>> class container = list>
- class SkipNode {
- public:
- typedef typename container<SkipNode<T, container>>::iterator NodeIterator;
- int mLevel;
- T mData;
- NodeIterator mNextInLevel;
- SkipNode(int level, T& data): mLevel(level), mData(data) {}
- };
- template <typename T>
- class SkipList {
- using NodeIterator = typename SkipNode<T>::NodeIterator;
- private:
- list<SkipNode<T>> mMainList;
- vector<NodeIterator> mHeadVec;
- vector<NodeIterator> mTailVec;
- public:
- SkipList(int totalLevels);
- void append(T& data, int level);
- void pop(int level);
- void pop();
- T front(int level);
- int size();
- void flush();
- list<pair<T, int>> dump();
- list<pair<T, int>> dump(int level);
- };
- template <typename T>
- SkipList<T>::SkipList(int totalLevels): mHeadVec(totalLevels, mMainList.end()),
- mTailVec(totalLevels, mMainList.end()) {}
- template <typename T>
- void SkipList<T>::append(T& data, int level) {
- if ( level < 0 || level >= mHeadVec.size()) {
- return;
- }
- SkipNode<T> node(level, data);
- node.mNextInLevel = mMainList.end();
- mMainList.push_back(node);
- auto iter = --mMainList.end();
- if (mHeadVec[level] == mMainList.end()) {
- mHeadVec[level] = iter;
- } else {
- (*mTailVec[level]).mNextInLevel = iter;
- }
- mTailVec[level] = iter;
- }
- template <typename T>
- void SkipList<T>::pop(int level) {
- if (mHeadVec[level] == mMainList.end()) {
- return;
- }
- if ((*mHeadVec[level]).mNextInLevel == mMainList.end()) {
- mTailVec[level] = mMainList.end();
- }
- auto tmp_iter = (*mHeadVec[level]).mNextInLevel;
- mMainList.erase(mHeadVec[level]);
- mHeadVec[level] = tmp_iter;
- }
- template <typename T>
- void SkipList<T>::pop() {
- pop(mMainList.front().mLevel);
- }
- template <typename T>
- T SkipList<T>::front(int level) {
- return (*mHeadVec[level]).mData;
- }
- template <typename T>
- int SkipList<T>::size() {
- return mMainList.size();
- }
- template <typename T>
- void SkipList<T>::flush() {
- mMainList.clear();
- for (int i = 0; i < mHeadVec.size(); i++) {
- mHeadVec[i] = mMainList.end();
- mTailVec[i] = mMainList.end();
- }
- }
- template <typename T>
- list<pair<T, int>> SkipList<T>::dump() {
- list<pair<T, int>> li;
- for_each(mMainList.begin(), mMainList.end(), [&](SkipNode<T> &item) {
- li.push_back(make_pair(item.mData, item.mLevel));
- });
- return li;
- }
- template <typename T>
- list<pair<T, int>> SkipList<T>::dump(int level) {
- list<pair<T, int>> li;
- auto head = mHeadVec[level];
- while (head != mMainList.end()) {
- li.push_back(make_pair((*head).mData, (*head).mLevel));
- head = (*head).mNextInLevel;
- }
- return li;
- }
- }
- #endif
|