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 const 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(NULL
) + "/" + 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
) {
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::ostream
& 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 strm
.write(buf1
, (RRDATA_BYTES
- j
+ 1) + (opcode
>> 5));
162 //std::cerr << "Encoding " << count << " symbols starting from " << base << std::endl;
166 uint64_t rrdata::write(std::ostream
& strm
) throw(std::bad_alloc
)
169 instance last_encode_end
;
170 memset(last_encode_end
.bytes
, 0, RRDATA_BYTES
);
173 instance encode_base
;
174 unsigned encode_count
= 0;
175 for(auto i
= rrset
.begin(); i
!= rrset
.end(); i
++) {
176 //std::cerr << "Considering " << *i << std::endl;
178 if(encode_count
== 0) {
179 //This is the first symbol.
182 } else if(predicted
== *i
&& encode_count
< 16843009) {
183 //Correct prediction.
187 flush_symbol(strm
, encode_base
, last_encode_end
, encode_count
);
188 last_encode_end
= predicted
;
196 flush_symbol(strm
, encode_base
, last_encode_end
, encode_count
);
200 uint64_t rrdata::read(std::istream
& strm
) throw(std::bad_alloc
)
204 memset(decoding
.bytes
, 0, RRDATA_BYTES
);
207 char buf1
[RRDATA_BYTES
];
209 strm
.read(&opcode
, 1);
212 unsigned validbytes
= (opcode
& 0x1F);
213 unsigned lengthbytes
= (opcode
& 0x60) >> 5;
215 strm
.read(buf1
, RRDATA_BYTES
- validbytes
);
216 memcpy(decoding
.bytes
+ validbytes
, buf1
, RRDATA_BYTES
- validbytes
);
218 strm
.read(buf2
, lengthbytes
);
220 repeat
= 2 + buf2
[0];
222 repeat
= 258 + static_cast<unsigned>(buf2
[0]) * 256 + buf2
[1];
224 repeat
= 65794 + static_cast<unsigned>(buf2
[0]) * 65536 + static_cast<unsigned>(buf2
[1]) *
226 //std::cerr << "Decoding " << count << " symbols starting from " << decoding << std::endl;
227 for(unsigned i
= 0; i
< repeat
; i
++)
228 rrdata::add(decoding
++);
234 const char* hexes
= "0123456789ABCDEF";
236 std::ostream
& operator<<(std::ostream
& os
, const struct rrdata::instance
& j
)
238 for(unsigned i
= 0; i
< 32; i
++) {
239 os
<< hexes
[j
.bytes
[i
] / 16] << hexes
[j
.bytes
[i
] % 16];
244 rrdata::instance
* rrdata::internal
;
247 //DBC0AB8CBAAC6ED4B7781E34057891E8B9D93AAE733DEF764C06957FF705DE00
248 //DBC0AB8CBAAC6ED4B7781E34057891E8B9D93AAE733DEF764C06957FF705DDF3