source: proto/CSV/csv2xml/util/bitsegment_iterator.hpp @ 2663

Last change on this file since 2663 was 2663, checked in by linmengl, 6 years ago

use store_unaligned to for speed

File size: 2.8 KB
Line 
1/*
2Forked from bitblock_iterator.hpp in the lib
3*/
4
5#include "bitblock.hpp"
6#include "../lib/bitblock_iterator.hpp"
7
8template <size_t N>
9class BitSegment
10{
11public:
12    BitBlock bit_blocks[N];
13    int count;
14
15    BitSegment()
16    {
17        clear();
18    }
19
20    void append(BitBlock &block)
21    {
22        bit_blocks[count] = block;
23        count ++;
24    }
25
26    void clear()
27    {
28        count = 0;
29    }
30
31    BitBlock* address()
32    {
33        return &bit_blocks[0];
34    }
35};
36
37template <class bitblock_t, class scanblock_t>
38class SegmentForwardScanner : Scanner<bitblock_t, scanblock_t> {
39
40    int N;
41
42public:
43    SegmentForwardScanner(){}
44    SegmentForwardScanner(const bitblock_t * s, int n) {
45        init(s);
46        N = n;
47    }
48
49    IDISA_ALWAYS_INLINE void init(const bitblock_t * s) {
50        this->strm = s;
51        this->pos = 0;
52        this->blk = 0;
53        this->scan_blk = *(scanblock_t *)s;
54    }
55
56    IDISA_ALWAYS_INLINE int32_t scan_to_next() {
57        while (this->blk < N * BLOCK_COUNT){
58            if((this->scan_blk != 0)){
59                this->pos = scan_forward_zeroes(this->scan_blk) + (this->blk * (sizeof(scanblock_t)*8));
60                this->scan_blk = this->scan_blk & (this->scan_blk-1);  // clear rightmost bit
61
62                return (this->pos);
63            }
64
65            this->blk++;
66            this->scan_blk = *((scanblock_t *)this->strm + this->blk);
67        };
68
69        this->pos = -1;
70        return (this->pos);
71    }
72
73    /* Set or reset the iterator to position new_pos. */
74    IDISA_ALWAYS_INLINE void move_to(uint32_t new_pos) {
75        const scanblock_t one_bit = 1;
76        this->blk = new_pos / (sizeof(scanblock_t)*8);
77        this->pos = new_pos % (sizeof(scanblock_t)*8);
78        this->scan_blk = ((scanblock_t *)this->strm)[this->blk];
79        // clear bit at pos and all positions to the right.
80        scanblock_t marker = one_bit << this->pos;
81        this->scan_blk = this->scan_blk &~((marker-1)|marker);
82    }
83
84    IDISA_ALWAYS_INLINE bool is_done() {return (-1==this->pos);}
85    IDISA_ALWAYS_INLINE void set_strm(const bitblock_t * strm) {this->strm = strm;}
86    IDISA_ALWAYS_INLINE const bitblock_t * get_strm() const {return this->strm;}
87    IDISA_ALWAYS_INLINE int32_t get_pos() const {return this->pos;}
88
89    static const int32_t BLOCK_COUNT = sizeof(bitblock_t) / sizeof(scanblock_t);
90};
91
92class BitSegmentForwardIterator
93{
94public:
95    BitSegmentForwardIterator() {}
96    BitSegmentForwardIterator(BitBlock *s, int n) : scanner(s, n)
97    {
98        scanner.scan_to_next();
99    }
100
101    bool is_end()
102    {
103        return scanner.is_done();
104    }
105
106    IDISA_ALWAYS_INLINE int32_t operator*()
107    {
108        return scanner.get_pos();
109    }
110
111    void operator++()
112    {
113        scanner.scan_to_next();
114    }
115
116private:
117    SegmentForwardScanner<BitBlock, ScanWord> scanner;
118};
119
Note: See TracBrowser for help on using the repository browser.