@@ -25,29 +25,48 @@ template <class T, class D>
2525class CompressedStack : public Stack <T,D>{
2626 friend class Problem <T,D>;
2727
28- private :
28+ public :
2929 CompressedStack<T,D>(int size, int space, int buffer, std::shared_ptr<T> context, std::streampos position = std::streampos(0 ));
30+ CompressedStack<T,D>(int size, int space, int buffer, const Signature<T,D> &sign);
3031
32+ private:
3133 // Internals
3234 Data<T,D> top (int k);
33- void push (const Data<T,D> &data);
34- Data<T,D> pop ();
35+ void push (const Data<T,D> &data, std::streampos position );
36+ Data<T,D> pop (Problem<T,D> &Problem );
3537 bool isempty ();
3638
39+ bool isSecondEmpty ();
40+
3741 // Setters
3842 void setContext (std::shared_ptr<T> context);
3943
44+ // Getters
45+ Block<T,D> getFirstPartial (int lvl);
46+ Block<T,D> getCompressed ();
47+ ExplicitPointer<T,D> getFirstExplicit ();
48+
4049 // IO
4150 std::string toString ();
4251
4352 // Push Internals
4453 void pushExplicit (std::shared_ptr<Data<T,D>> elt);
45- void pushCompressed (std::shared_ptr<Data<T,D>> elt, int lvl);
54+ void pushCompressed (std::shared_ptr<Data<T,D>> elt, int lvl, std::streampos position );
4655 Data<T,D> top ();
4756 int topIndex ();
4857 void compress ();
4958 void resetBlock (Signature<T,D> sign, int lvl);
5059
60+ // Pop Internals
61+ void reconstruct (Problem<T,D> &problem);
62+ void reconstruct (Problem<T,D> &problem,const Signature<T,D> &sign, int lvl);
63+ void popFirst ();
64+ void popSecond ();
65+ void propagateFirst (int index, int lvl);
66+ void propagateSecond (int index, int lvl);
67+ void emptyFirst (int index, int lvl);
68+ void emptySecond (int index, int lvl);
69+
5170 // Structure constraints
5271 int mSize ; // (Expected) size of the input in #elements
5372 int mSpace ; // Maximum space order of the compressed stack
@@ -84,6 +103,20 @@ CompressedStack<T,D>::CompressedStack(int size, int space, int buffer, std::shar
84103 mContext = context;
85104}
86105
106+ template <class T , class D >
107+ CompressedStack<T,D>::CompressedStack(int size, int space, int buffer, const Signature<T,D> &sign)
108+ : mFirst (space, int ( ceil(log(size)/log(space)-.1 )))
109+ , mSecond (space, int ( ceil(log(size)/log(space)-.1 )))
110+ , mBuffer (buffer){
111+ mSize = size;
112+ mSpace = space;
113+ mDepth = int ( ceil (log (size)/log (space)-.1 ));
114+ mCompressed = initBlock<T,D>(mSpace );
115+
116+ mPosition = sign.mPosition ;
117+ mContext = sign.mContext ;
118+ }
119+
87120/* ==============================================================================
88121 Setters : setContext
89122==============================================================================*/
@@ -92,6 +125,24 @@ void CompressedStack<T,D>::setContext(std::shared_ptr<T> context){
92125 mContext = context;
93126}
94127
128+ /* ==============================================================================
129+ Getters : getFirstPartial
130+ ==============================================================================*/
131+ template <class T , class D >
132+ Block<T,D> CompressedStack<T,D>::getFirstPartial(int lvl){
133+ return mFirst .mPartial [lvl];
134+ }
135+
136+ template <class T , class D >
137+ Block<T,D> CompressedStack<T,D>::getCompressed(){
138+ return mCompressed ;
139+ }
140+
141+ template <class T , class D >
142+ ExplicitPointer<T,D> CompressedStack<T,D>::getFirstExplicit(){
143+ return mFirst .mExplicit ;
144+ }
145+
95146/* ==============================================================================
96147 IO : toString
97148==============================================================================*/
@@ -111,9 +162,18 @@ std::string CompressedStack<T,D>::toString(){
111162 return str;
112163}
113164
165+ /* ==============================================================================
166+
167+ ==============================================================================*/
168+
114169/* ==============================================================================
115170 Stack Functions: push, pop, isempty, compress
116171==============================================================================*/
172+ template <class T , class D >
173+ bool CompressedStack<T,D>::isSecondEmpty(){
174+ return mSecond .mPartial .empty ();
175+ }
176+
117177// Function that compress the top block of mSecond to a sign in mCompressed
118178template <class T , class D >
119179void CompressedStack<T,D>::compress(){
@@ -136,7 +196,7 @@ void CompressedStack<T,D>::resetBlock(Signature<T,D> sign, int lvl){
136196
137197// Function push that push the data in explicit and index in partial/compressed
138198template <class T , class D >
139- void CompressedStack<T,D>::push(const Data<T,D> &elt){
199+ void CompressedStack<T,D>::push(const Data<T,D> &elt, std::streampos position ){
140200 // update the buffer (if buffer size is bigger than 0)
141201 std::shared_ptr<Data<T,D>> ptr_elt = std::make_shared<Data<T,D>>(elt);
142202 mBuffer .push (ptr_elt);
@@ -145,7 +205,7 @@ void CompressedStack<T,D>::push(const Data<T,D> &elt){
145205 // update the compressed Blocks at each levels (including fully compressed)
146206 for (int lvl = 0 ; lvl < mDepth - 1 ; lvl++) {
147207 std::cout << " Pushing on level " << lvl << std::endl;
148- pushCompressed (ptr_elt, lvl);
208+ pushCompressed (ptr_elt, lvl, position );
149209 }
150210}
151211
@@ -188,11 +248,11 @@ void CompressedStack<T,D>::pushExplicit(std::shared_ptr<Data<T,D>> elt){
188248
189249// Function push for the part. and fully compressed members of the stack
190250template <class T , class D >
191- void CompressedStack<T,D>::pushCompressed(std::shared_ptr<Data<T,D>> elt, int lvl){
251+ void CompressedStack<T,D>::pushCompressed(std::shared_ptr<Data<T,D>> elt, int lvl, std::streampos position ){
192252 int distSubBlock = std::pow (mSpace ,(mDepth - lvl));
193253 int distBlock = distSubBlock * mSpace ;
194254 int index = elt->mIndex ;
195- Signature<T,D> sign (index, mPosition , mContext );
255+ Signature<T,D> sign (index, position , mContext );
196256
197257 if (mFirst .isempty (lvl)) {
198258 mFirst .push (sign, lvl);
@@ -229,9 +289,156 @@ void CompressedStack<T,D>::pushCompressed(std::shared_ptr<Data<T,D>> elt, int lv
229289}
230290
231291template <class T , class D >
232- Data<T,D> CompressedStack<T,D>::pop(){
233- Data<T,D> d (1 ,1 );
234- return d;
292+ void CompressedStack<T,D>::popFirst(){
293+ // Pop the explicit data from the 1st component
294+ mFirst .mExplicit .pop_back ();
295+
296+ int index = topIndex ();
297+ if (mDepth > 1 ) {
298+ if (mFirst .mExplicit .empty ()) {
299+ emptyFirst (index, mDepth - 1 );
300+ } else {
301+ int newIndex = (*(mFirst .mExplicit .back ())).mIndex ;
302+ propagateFirst (newIndex, mDepth - 1 );
303+ }
304+ }
305+ }
306+
307+ template <class T , class D >
308+ void CompressedStack<T,D>::popSecond(){
309+ // Pop the explicit data from the 2nd component
310+ mSecond .mExplicit .pop_back ();
311+
312+ int index = topIndex ();
313+ if (mDepth > 1 ) {
314+ if (mSecond .mExplicit .empty ()) {
315+ emptySecond (index, mDepth - 1 );
316+ } else {
317+ int newIndex = (*(mSecond .mExplicit .back ())).mIndex ;
318+ propagateSecond (newIndex, mDepth - 1 );
319+ }
320+ }
321+ }
322+
323+ template <class T , class D >
324+ void CompressedStack<T,D>::propagateFirst(int index, int lvl){
325+ for (int i = 0 ; i < lvl; i++) {
326+ mFirst .mPartial [i].back ().mLast = index;
327+ }
328+ }
329+
330+ template <class T , class D >
331+ void CompressedStack<T,D>::propagateSecond(int index, int lvl){
332+ if (mFirst .mPartial .empty ()) {
333+ mSecond .mPartial [lvl].back ().mLast = index;
334+ if (lvl > 0 ) {
335+ propagateSecond (index, lvl - 1 );
336+ }
337+ } else {
338+ propagateFirst (index, lvl);
339+ }
340+ }
341+
342+ template <class T , class D >
343+ void CompressedStack<T,D>::emptyFirst(int index, int lvl){
344+ mFirst .mPartial [lvl].pop_back ();
345+ if (lvl > 0 ) {
346+ if (mFirst .mPartial [lvl].size () == 0 ) {
347+ emptyFirst (index, lvl - 1 );
348+ } else {
349+ int newIndex = mFirst .mPartial [lvl].back ().mLast ;
350+ propagateFirst (newIndex, lvl - 1 );
351+ }
352+ }
353+ }
354+
355+ template <class T , class D >
356+ void CompressedStack<T,D>::emptySecond(int index, int lvl){
357+ if (mFirst .mPartial [lvl].empty ()) {
358+ mSecond .mPartial [lvl].pop_back ();
359+ if (lvl > 0 ) {
360+ if (mSecond .mPartial [lvl].size () == 0 ) {
361+ emptySecond (index, lvl - 1 );
362+ } else {
363+ int newIndex = mSecond .mPartial [lvl].back ().mLast ;
364+ propagateSecond (newIndex, lvl - 1 );
365+ }
366+ }
367+ } else {
368+ emptyFirst (index, lvl);
369+ }
370+ }
371+
372+ // Look for the first level of information available to reconstruct
373+ template <class T , class D >
374+ void CompressedStack<T,D>::reconstruct(Problem<T,D> &problem){
375+ for (int i = 1 ; i <= mDepth ; i++) {
376+ int lvl = mDepth - 1 - i; // lvl == -1 is for the fully compressed part
377+ if (lvl < 0 ) {
378+ Signature<T,D> sign = Signature<T,D>(mCompressed .back ());
379+ reconstruct (problem, sign, lvl + 1 );
380+ break ;
381+ } else {
382+ if (mFirst .mPartial [lvl].empty ()) {
383+ Signature<T,D> sign = Signature<T,D>(mFirst .mPartial [lvl].back ());
384+ reconstruct (problem, sign, lvl + 1 );
385+ break ;
386+ } else if (mSecond .mPartial [lvl].empty ()) {
387+ Signature<T,D> sign = Signature<T,D>(mSecond .mPartial [lvl].back ());
388+ reconstruct (problem, sign, lvl + 1 );
389+ break ;
390+ }
391+ }
392+ }
393+ }
394+
395+ // Reconstruct an auxiliary stack based on the signature found above
396+ template <class T , class D >
397+ void CompressedStack<T,D>::reconstruct(Problem<T,D> &problem, const Signature<T,D> &sign, int lvl){
398+ std::streampos posReminder = mPosition ;
399+ int indexReminder = problem.mIndex ;
400+
401+ problem.mIndex = sign.mFirst ;
402+ int auxSize = std::pow (mSpace , mDepth - lvl);
403+ std::shared_ptr<Stack<T,D>> auxStack = std::make_shared<CompressedStack<T,D>>(auxSize, mSpace , mBuffer .mSize , sign);
404+
405+ // Swap stack pointers + run + swap back
406+ swap (problem.mStack , auxStack);
407+ problem.run (sign.mLast - sign.mFirst );
408+ swap (problem.mStack , auxStack);
409+ problem.mIndex = indexReminder;
410+ mPosition = posReminder;
411+
412+ // Copy the First component of the reconstructed stack into the main stack
413+ int auxDepth = int ( ceil (log (auxSize)/log (mSpace )-.1 ));
414+ int delta = mDepth - auxDepth;
415+ for (int i = 0 ; i < auxDepth; i++) {
416+ mSecond .mPartial [delta + i] = (*auxStack).getFirstPartial (i);
417+ }
418+ if (lvl == 0 ) {
419+ if (!(*auxStack).isSecondEmpty ()) {
420+ (*auxStack).compress ();
421+ }
422+ mCompressed = (*auxStack).getCompressed ();
423+ }
424+ mSecond .mExplicit = (*auxStack).getFirstExplicit ();
425+ }
426+
427+ template <class T , class D >
428+ Data<T,D> CompressedStack<T,D>::pop(Problem<T,D> &problem){
429+ std::shared_ptr<Data<T,D>> elt;
430+ if (mFirst .mExplicit .empty ()) {
431+ if (mSecond .mExplicit .empty ()) {
432+ // Reconstruct the compressed stack with the first available signature
433+ reconstruct (problem);
434+ }
435+ elt = mSecond .mExplicit .back ();
436+ popSecond ();
437+ } else {
438+ elt = mFirst .mExplicit .back ();
439+ popFirst ();
440+ }
441+ return *elt;
235442}
236443
237444template <class T , class D >
@@ -251,9 +458,14 @@ Data<T,D> CompressedStack<T,D>::top(){
251458}
252459// Top index of a Compressed Stack
253460template <class T , class D >
254- int topIndex (){
255- Data<T,D> elt = CompressedStack<T,D>::top ();
256- return elt.getIndex ();
461+ int CompressedStack<T,D>::topIndex(){
462+ if (mFirst .mExplicit .empty ()) {
463+ if (mSecond .mExplicit .empty ()) {
464+ return mCompressed .back ().mLast ;
465+ }
466+ return (*(mSecond .mExplicit .back ())).mIndex ;
467+ }
468+ return (*(mFirst .mExplicit .back ())).mIndex ;
257469}
258470
259471#endif /* COMPRESSEDSTACK */
0 commit comments