SDSL: Succinct Data Structure Library
A C++ template library for succinct data structures
|
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