SDSL: Succinct Data Structure Library
A C++ template library for succinct data structures
 All Classes Namespaces Files Functions Variables Typedefs Friends
sdsl/include/sdsl/sorted_multi_stack_support.hpp
Go to the documentation of this file.
00001 /* sdsl - succinct data structures library
00002     Copyright (C) 2010 Simon Gog
00003 
00004     This program is free software: you can redistribute it and/or modify
00005     it under the terms of the GNU General Public License as published by
00006     the Free Software Foundation, either version 3 of the License, or
00007     (at your option) any later version.
00008 
00009     This program is distributed in the hope that it will be useful,
00010     but WITHOUT ANY WARRANTY; without even the implied warranty of
00011     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012     GNU General Public License for more details.
00013 
00014     You should have received a copy of the GNU General Public License
00015     along with this program.  If not, see http://www.gnu.org/licenses/ .
00016 */
00022 #ifndef INCLUDED_SDSL_SORTED_MULTI_STACK_SUPPORT
00023 #define INCLUDED_SDSL_SORTED_MUTLI_STACK_SUPPORT
00024 
00025 #include "int_vector.hpp"
00026 #include "bitmagic.hpp"
00027 #include <vector>
00028 
00030 namespace sdsl
00031 {
00032 
00034 
00037 class sorted_multi_stack_support
00038 {
00039     public:
00040         typedef int_vector<64>::size_type size_type;
00041     private:
00042         size_type m_n;   // Size of the supported vector.
00043         size_type m_cnt; // Counter for the indices on the stack.
00044         size_type m_top; // Topmost index of the stack.
00045         int_vector<64> m_stack; // Memory for the stack.
00046         int_vector<64> m_duplication_stack; // Memory for the duplications
00047 
00048         inline size_type block_nr(size_type x) {
00049             return x/63;
00050         }; // maybe we can speed this up with bit hacks
00051         inline size_type block_pos(size_type x) {
00052             return x%63;
00053         }; // maybe we can speed this up with bit hacks
00054     public:
00056 
00058         sorted_multi_stack_support(size_type n);
00059 
00060         sorted_multi_stack_support(const sorted_multi_stack_support& sis);
00061         ~sorted_multi_stack_support() {};
00062 
00065         bool empty() const {
00066             return 0==m_cnt;
00067         };
00068 
00072         const size_type top() const;
00073 
00078         bool pop();
00079 
00085         bool push(size_type x);
00086 
00089         size_type size()const {
00090             return m_cnt;
00091         };
00092 
00093         size_type serialize(std::ostream& out)const;
00094         void load(std::istream& in);
00095 
00097 
00099         sorted_multi_stack_support& operator=(const sorted_multi_stack_support& sis);
00100 
00102 
00107         bool operator==(const sorted_multi_stack_support& sis)const;
00109 
00114         bool operator!=(const sorted_multi_stack_support& sis)const;
00115 
00116 };
00117 
00118 inline sorted_multi_stack_support::sorted_multi_stack_support(size_type n):m_n(n), m_cnt(0), m_top(0), m_stack(), m_duplication_stack()
00119 {
00120     m_stack = int_vector<64>(block_nr(m_n+1)+1, 0);
00121     m_stack[0] = 1;
00122     m_duplication_stack = int_vector<64>((m_n>>6)+1, 0);
00123 }
00124 
00125 inline sorted_multi_stack_support::sorted_multi_stack_support(const sorted_multi_stack_support& sis):m_n(sis.m_n), m_cnt(sis.m_cnt), m_top(sis.m_top), m_stack(), m_duplication_stack()
00126 {
00127     m_stack = sis.m_stack;
00128     m_duplication_stack = sis.m_duplication_stack;
00129 }
00130 
00131 inline sorted_multi_stack_support& sorted_multi_stack_support::operator=(const sorted_multi_stack_support& sis)
00132 {
00133     if (this != &sis) {
00134         m_n                     = sis.m_n;
00135         m_cnt           = sis.m_cnt;
00136         m_top           = sis.m_top;
00137         m_stack         = sis.m_stack;
00138         m_duplication_stack = sis.m_duplication_stack;
00139     }
00140     return *this;
00141 }
00142 
00143 inline bool sorted_multi_stack_support::operator==(const sorted_multi_stack_support& sis)const
00144 {
00145     return m_n == sis.m_n and m_cnt == sis.m_cnt and m_top == sis.m_top and m_stack == sis.m_stack
00146            and m_duplication_stack == sis.m_duplication_stack;
00147 }
00148 
00149 inline bool sorted_multi_stack_support::operator!=(const sorted_multi_stack_support& sis)const
00150 {
00151     return !(*this==sis);
00152 }
00153 
00154 inline const sorted_multi_stack_support::size_type sorted_multi_stack_support::top()const
00155 {
00156     return m_top-1;
00157 }
00158 
00159 inline bool sorted_multi_stack_support::push(size_type x)
00160 {
00161     x += 1;
00162     size_type bn = block_nr(x);
00163     if (0 == ((m_stack[bn] >> block_pos(x))&1)) { // check if x is not already on the stack
00164         m_stack[bn] ^= (1ULL << block_pos(x));
00165         if (bn > 0 and m_stack[bn-1] == 0) {
00166             m_stack[bn-1] = 0x8000000000000000ULL | m_top;
00167         }
00168         m_top = x;
00169         // write a 0 to the duplication stack
00170         // do nothing as stack is initialized with zeros
00171         ++m_cnt;        //< increment counter
00172         return true;
00173     } else { // if the element is already on the stack
00174         // write a 1 to the duplication stack
00175         m_duplication_stack[m_cnt>>6] ^= (1ULL << (m_cnt&0x3F));
00176         ++m_cnt;        //< increment counter
00177         return false;
00178     }
00179 }
00180 
00181 inline bool sorted_multi_stack_support::pop()
00182 {
00183     if (m_cnt) {
00184         --m_cnt; //< decrement counter
00185         if ((m_duplication_stack[m_cnt>>6]>>(m_cnt&0x3F))&1) { // if it's a duplication
00186             m_duplication_stack[m_cnt>>6] ^= (1ULL << (m_cnt&0x3F));  // delete 1
00187             return false;
00188         } else {
00189             size_type bn = block_nr(m_top);
00190             uint64_t w = m_stack[ bn ];
00191             assert((w>>63) == 0);    // highest bit is not set, as the block contains no pointer
00192             w ^= (1ULL << block_pos(m_top));
00193             m_stack[ bn ] = w;
00194             if (w>0) {
00195                 m_top = bn*63 + bit_magic::l1BP(w);
00196             } else { // w==0 and cnt>0
00197                 assert(bn > 0);
00198                 w = m_stack[ bn-1 ];
00199                 if ((w>>63) == 0) { // highest bit is not set => the block contains no pointer
00200                     assert(w>0);
00201                     m_top = (bn-1)*63 + bit_magic::l1BP(w);
00202                 } else { // block contains pointers
00203                     m_stack[bn-1] = 0;
00204                     m_top = w&0x7FFFFFFFFFFFFFFFULL;
00205                 }
00206             }
00207             return true;
00208         }
00209     }
00210     return false;
00211 }
00212 
00213 inline sorted_multi_stack_support::size_type sorted_multi_stack_support::serialize(std::ostream& out)const
00214 {
00215     size_type written_bytes = 0;
00216     written_bytes += util::write_member(m_n, out);
00217     written_bytes += util::write_member(m_top, out);
00218     written_bytes += util::write_member(m_cnt, out);
00219     written_bytes += m_stack.serialize(out);
00220     written_bytes += m_duplication_stack.serialize(out);
00221     return written_bytes;
00222 }
00223 
00224 inline void sorted_multi_stack_support::load(std::istream& in)
00225 {
00226     util::read_member(m_n, in);
00227     util::read_member(m_top, in);
00228     util::read_member(m_cnt, in);
00229     m_stack.load(in);
00230     m_duplication_stack.load(in);
00231 }
00232 
00233 }// end namespace sdsl
00234 
00235 #endif // end file