1 /*
2  * Copyright (C) 2015 Nicolas Bonnefon and other contributors
3  *
4  * This file is part of glogg.
5  *
6  * glogg is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * glogg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with glogg.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #ifndef LINEPOSITIONARRAY_H
21 #define LINEPOSITIONARRAY_H
22 
23 #include <vector>
24 
25 #include "data/compressedlinestorage.h"
26 
27 typedef std::vector<uint64_t> SimpleLinePositionStorage;
28 
29 // This class is a list of end of lines position,
30 // in addition to a list of uint64_t (positions within the files)
31 // it can keep track of whether the final LF was added (for non-LF terminated
32 // files) and remove it when more data are added.
33 template <typename Storage>
34 class LinePosition
35 {
36   public:
37     template <typename> friend class LinePosition;
38 
39     // Default constructor
LinePosition()40     LinePosition() : array()
41     { fakeFinalLF_ = false; }
42     // Copy constructor (slow: deleted)
43     LinePosition( const LinePosition& orig ) = delete;
44     // Move assignement
45     LinePosition& operator=( LinePosition&& orig )
46     { array = std::move( orig.array );
47       fakeFinalLF_ = orig.fakeFinalLF_;
48       return *this; }
49 
50     // Add a new line position at the given position
51     // Invariant: pos must be greater than the previous one
52     // (this is NOT checked!)
append(uint64_t pos)53     inline void append( uint64_t pos )
54     {
55         if ( fakeFinalLF_ )
56             array.pop_back();
57 
58         array.push_back( pos );
59         fakeFinalLF_ = false;
60     }
61     // Size of the array
size()62     inline int size() const
63     { return array.size(); }
64     // Extract an element
at(int i)65     inline uint64_t at( int i ) const
66     { return array.at( i ); }
67     inline uint64_t operator[]( int i ) const
68     { return array.at( i ); }
69     // Set the presence of a fake final LF
70     // Must be used after 'append'-ing a fake LF at the end.
71     void setFakeFinalLF( bool finalLF=true )
72     { fakeFinalLF_ = finalLF; }
73 
74     // Add another list to this one, removing any fake LF on this list.
75     // Invariant: all pos in other must be greater than any pos in this
76     // (this is NOT checked!)
append_list(const LinePosition<SimpleLinePositionStorage> & other)77     void append_list( const LinePosition<SimpleLinePositionStorage>& other )
78     {
79         // If our final LF is fake, we remove it
80         if ( fakeFinalLF_ )
81             this->array.pop_back();
82 
83         // Append the arrays
84         this->array.append_list( other.array );
85         //array += other.array;
86 
87         // In case the 'other' object has a fake LF
88         this->fakeFinalLF_ = other.fakeFinalLF_;
89     }
90 
91   private:
92     Storage array;
93     bool fakeFinalLF_;
94 };
95 
96 // Use the non-optimised storage
97 typedef LinePosition<SimpleLinePositionStorage> FastLinePositionArray;
98 //typedef LinePosition<SimpleLinePositionStorage> LinePositionArray;
99 
100 typedef LinePosition<CompressedLinePositionStorage> LinePositionArray;
101 
102 #endif
103