14 // ABCDEF0123456789XXXXXX
16 rrdata::instance::instance() throw(std::bad_alloc
)
18 std::string rnd
= get_random_hexstring(2 * RRDATA_BYTES
);
19 memset(bytes
, 0, RRDATA_BYTES
);
20 for(unsigned i
= 0; i
< 2 * RRDATA_BYTES
; i
++) {
23 x
= x
- x
/ 16 * 9 - 1;
24 bytes
[i
/ 2] = 16 * bytes
[i
/ 2] + x
;
28 rrdata::instance::instance(unsigned char* b
) throw()
30 memcpy(bytes
, b
, RRDATA_BYTES
);
33 bool rrdata::instance::operator<(const struct instance
& i
) const throw()
35 for(unsigned j
= 0; j
< RRDATA_BYTES
; j
++)
36 if(bytes
[j
] < i
.bytes
[j
])
38 else if(bytes
[j
] > i
.bytes
[j
])
43 bool rrdata::instance::operator==(const struct instance
& i
) const throw()
45 for(unsigned j
= 0; j
< RRDATA_BYTES
; j
++)
46 if(bytes
[j
] != i
.bytes
[j
])
51 const struct rrdata::instance
rrdata::instance::operator++(int) throw()
58 struct rrdata::instance
& rrdata::instance::operator++() throw()
61 for(unsigned i
= 31; i
< 32; i
--) {
62 unsigned newcarry
= (bytes
[i
] == 255 && carry
);
71 std::set
<rrdata::instance
> rrset
;
72 std::ifstream ihandle
;
73 std::ofstream ohandle
;
75 std::string current_project
;
78 void rrdata::read_base(const std::string
& project
) throw(std::bad_alloc
)
80 if(project
== current_project
)
82 std::set
<rrdata::instance
> new_rrset
;
83 std::string filename
= get_config_path() + "/" + project
+ ".rr";
88 ihandle
.open(filename
.c_str(), std::ios_base::in
);
90 unsigned char bytes
[RRDATA_BYTES
];
91 ihandle
.read(reinterpret_cast<char*>(bytes
), RRDATA_BYTES
);
93 //std::cerr << "Loaded symbol: " << k << std::endl;
97 ohandle
.open(filename
.c_str(), std::ios_base::out
| std::ios_base::app
);
101 current_project
= project
;
104 void rrdata::close() throw()
106 current_project
= "";
112 void rrdata::add(const struct rrdata::instance
& i
) throw(std::bad_alloc
)
114 if(rrset
.insert(i
).second
&& handle_open
) {
115 //std::cerr << "New symbol: " << i << std::endl;
116 ohandle
.write(reinterpret_cast<const char*>(i
.bytes
), RRDATA_BYTES
);
121 void rrdata::add_internal() throw(std::bad_alloc
)
124 internal
= new instance();
130 void flush_symbol(std::vector
<char>& strm
, const rrdata::instance
& base
, const rrdata::instance
& predicted
,
134 char buf1
[RRDATA_BYTES
+ 4];
140 } else if(count
< 258) {
143 } else if(count
< 65794) {
151 for(j
= 0; j
< 31; j
++)
152 if(base
.bytes
[j
] != predicted
.bytes
[j
])
156 memcpy(buf1
+ 1, base
.bytes
+ j
, RRDATA_BYTES
- j
);
157 buf2
[0] = (count
- bias
) >> 16;
158 buf2
[1] = (count
- bias
) >> 8;
159 buf2
[2] = (count
- bias
);
160 memcpy(buf1
+ (RRDATA_BYTES
- j
+ 1), buf2
+ (3 - (opcode
>> 5)), opcode
>> 5);
161 for(size_t s
= 0; s
< (RRDATA_BYTES
- j
+ 1) + (opcode
>> 5); s
++)
162 strm
.push_back(buf1
[s
]);
163 //std::cerr << "Encoding " << count << " symbols starting from " << base << std::endl;
167 uint64_t rrdata::write(std::vector
<char>& strm
) throw(std::bad_alloc
)
171 instance last_encode_end
;
172 memset(last_encode_end
.bytes
, 0, RRDATA_BYTES
);
175 instance encode_base
;
176 unsigned encode_count
= 0;
177 for(auto i
: rrset
) {
178 //std::cerr << "Considering " << *i << std::endl;
180 if(encode_count
== 0) {
181 //This is the first symbol.
184 } else if(predicted
== i
&& encode_count
< 16843009) {
185 //Correct prediction.
189 flush_symbol(strm
, encode_base
, last_encode_end
, encode_count
);
190 last_encode_end
= predicted
;
198 flush_symbol(strm
, encode_base
, last_encode_end
, encode_count
);
205 uint64_t rrdata::read(std::vector
<char>& strm
, bool dummy
) throw(std::bad_alloc
)
210 memset(decoding
.bytes
, 0, RRDATA_BYTES
);
211 while(ptr
< strm
.size()) {
213 char buf1
[RRDATA_BYTES
];
215 opcode
= strm
[ptr
++];
216 unsigned validbytes
= (opcode
& 0x1F);
217 unsigned lengthbytes
= (opcode
& 0x60) >> 5;
219 memcpy(buf1
, &strm
[ptr
], RRDATA_BYTES
- validbytes
);
220 ptr
+= (RRDATA_BYTES
- validbytes
);
221 memcpy(decoding
.bytes
+ validbytes
, buf1
, RRDATA_BYTES
- validbytes
);
222 if(lengthbytes
> 0) {
223 memcpy(buf2
, &strm
[ptr
], lengthbytes
);
227 repeat
= 2 + buf2
[0];
229 repeat
= 258 + static_cast<unsigned>(buf2
[0]) * 256 + buf2
[1];
231 repeat
= 65794 + static_cast<unsigned>(buf2
[0]) * 65536 + static_cast<unsigned>(buf2
[1]) *
233 //std::cerr << "Decoding " << count << " symbols starting from " << decoding << std::endl;
235 for(unsigned i
= 0; i
< repeat
; i
++)
236 rrdata::add(decoding
++);
245 uint64_t rrdata::count(std::vector
<char>& strm
) throw(std::bad_alloc
)
247 return read(strm
, true);
250 const char* hexes
= "0123456789ABCDEF";
252 std::ostream
& operator<<(std::ostream
& os
, const struct rrdata::instance
& j
)
254 for(unsigned i
= 0; i
< 32; i
++) {
255 os
<< hexes
[j
.bytes
[i
] / 16] << hexes
[j
.bytes
[i
] % 16];
260 rrdata::instance
* rrdata::internal
;
263 //DBC0AB8CBAAC6ED4B7781E34057891E8B9D93AAE733DEF764C06957FF705DE00
264 //DBC0AB8CBAAC6ED4B7781E34057891E8B9D93AAE733DEF764C06957FF705DDF3