1 #include "core/misc.hpp"
2 #include "core/rrdata.hpp"
15 // ABCDEF0123456789XXXXXX
17 rrdata::instance::instance() throw(std::bad_alloc
)
19 std::string rnd
= get_random_hexstring(2 * RRDATA_BYTES
);
20 memset(bytes
, 0, RRDATA_BYTES
);
21 for(unsigned i
= 0; i
< 2 * RRDATA_BYTES
; i
++) {
24 x
= x
- x
/ 16 * 9 - 1;
25 bytes
[i
/ 2] = 16 * bytes
[i
/ 2] + x
;
29 rrdata::instance::instance(unsigned char* b
) throw()
31 memcpy(bytes
, b
, RRDATA_BYTES
);
34 bool rrdata::instance::operator<(const struct instance
& i
) const throw()
36 for(unsigned j
= 0; j
< RRDATA_BYTES
; j
++)
37 if(bytes
[j
] < i
.bytes
[j
])
39 else if(bytes
[j
] > i
.bytes
[j
])
44 bool rrdata::instance::operator==(const struct instance
& i
) const throw()
46 for(unsigned j
= 0; j
< RRDATA_BYTES
; j
++)
47 if(bytes
[j
] != i
.bytes
[j
])
52 const struct rrdata::instance
rrdata::instance::operator++(int) throw()
59 struct rrdata::instance
& rrdata::instance::operator++() throw()
62 for(unsigned i
= 31; i
< 32; i
--) {
63 unsigned newcarry
= (bytes
[i
] == 255 && carry
);
72 std::set
<rrdata::instance
> rrset
;
73 std::ifstream ihandle
;
74 std::ofstream ohandle
;
76 std::string current_project
;
78 const char* hexes
= "0123456789ABCDEF";
81 void rrdata::read_base(const std::string
& project
, bool lazy
) throw(std::bad_alloc
)
83 if(project
== current_project
&& (!lazy_mode
|| lazy
))
86 std::set
<rrdata::instance
> new_rrset
;
88 current_project
= project
;
95 std::set
<rrdata::instance
> new_rrset
;
96 if(project
== current_project
)
98 std::string filename
= get_config_path() + "/" + safe_filename(project
) + ".rr";
103 ihandle
.open(filename
.c_str(), std::ios_base::in
| std::ios_base::binary
);
105 unsigned char bytes
[RRDATA_BYTES
];
106 ihandle
.read(reinterpret_cast<char*>(bytes
), RRDATA_BYTES
);
108 //std::cerr << "Loaded symbol: " << k << std::endl;
112 ohandle
.open(filename
.c_str(), std::ios_base::out
| std::ios_base::app
| std::ios_base::binary
);
115 if(project
== current_project
&& lazy_mode
&& !lazy
) {
116 //Finish the project creation, write all.
117 for(auto i
: rrset
) {
118 ohandle
.write(reinterpret_cast<const char*>(i
.bytes
), RRDATA_BYTES
);
123 current_project
= project
;
127 void rrdata::close() throw()
129 current_project
= "";
135 void rrdata::add(const struct rrdata::instance
& i
) throw(std::bad_alloc
)
137 if(rrset
.insert(i
).second
&& handle_open
) {
138 //std::cerr << "New symbol: " << i << std::endl;
139 ohandle
.write(reinterpret_cast<const char*>(i
.bytes
), RRDATA_BYTES
);
144 void rrdata::add_internal() throw(std::bad_alloc
)
147 internal
= new instance();
153 void flush_symbol(std::vector
<char>& strm
, const rrdata::instance
& base
, const rrdata::instance
& predicted
,
157 char buf1
[RRDATA_BYTES
+ 4];
163 } else if(count
< 258) {
166 } else if(count
< 65794) {
174 for(j
= 0; j
< 31; j
++)
175 if(base
.bytes
[j
] != predicted
.bytes
[j
])
179 memcpy(buf1
+ 1, base
.bytes
+ j
, RRDATA_BYTES
- j
);
180 buf2
[0] = (count
- bias
) >> 16;
181 buf2
[1] = (count
- bias
) >> 8;
182 buf2
[2] = (count
- bias
);
183 memcpy(buf1
+ (RRDATA_BYTES
- j
+ 1), buf2
+ (3 - (opcode
>> 5)), opcode
>> 5);
184 for(size_t s
= 0; s
< (RRDATA_BYTES
- j
+ 1) + (opcode
>> 5); s
++)
185 strm
.push_back(buf1
[s
]);
186 //std::cerr << "Encoding " << count << " symbols starting from " << base << std::endl;
190 uint64_t rrdata::write(std::vector
<char>& strm
) throw(std::bad_alloc
)
194 instance last_encode_end
;
195 memset(last_encode_end
.bytes
, 0, RRDATA_BYTES
);
198 instance encode_base
;
199 unsigned encode_count
= 0;
200 for(auto i
: rrset
) {
201 //std::cerr << "Considering " << *i << std::endl;
203 if(encode_count
== 0) {
204 //This is the first symbol.
207 } else if(predicted
== i
&& encode_count
< 16843009) {
208 //Correct prediction.
212 flush_symbol(strm
, encode_base
, last_encode_end
, encode_count
);
213 last_encode_end
= predicted
;
221 flush_symbol(strm
, encode_base
, last_encode_end
, encode_count
);
228 uint64_t rrdata::read(std::vector
<char>& strm
, bool dummy
) throw(std::bad_alloc
)
233 memset(decoding
.bytes
, 0, RRDATA_BYTES
);
234 while(ptr
< strm
.size()) {
236 unsigned char buf1
[RRDATA_BYTES
];
237 unsigned char buf2
[3];
238 opcode
= strm
[ptr
++];
239 unsigned validbytes
= (opcode
& 0x1F);
240 unsigned lengthbytes
= (opcode
& 0x60) >> 5;
242 memcpy(buf1
, &strm
[ptr
], RRDATA_BYTES
- validbytes
);
243 ptr
+= (RRDATA_BYTES
- validbytes
);
244 memcpy(decoding
.bytes
+ validbytes
, buf1
, RRDATA_BYTES
- validbytes
);
245 if(lengthbytes
> 0) {
246 memcpy(buf2
, &strm
[ptr
], lengthbytes
);
250 repeat
= 2 + static_cast<unsigned>(buf2
[0]);
252 repeat
= 258 + static_cast<unsigned>(buf2
[0]) * 256 + buf2
[1];
254 repeat
= 65794 + static_cast<unsigned>(buf2
[0]) * 65536 + static_cast<unsigned>(buf2
[1]) *
256 //std::cerr << "Decoding " << repeat << " symbols starting from " << decoding << std::endl;
258 for(unsigned i
= 0; i
< repeat
; i
++)
259 rrdata::add(decoding
++);
268 uint64_t rrdata::count(std::vector
<char>& strm
) throw(std::bad_alloc
)
270 return read(strm
, true);
273 uint64_t rrdata::count() throw()
275 uint64_t c
= rrset
.size();
283 std::ostream
& operator<<(std::ostream
& os
, const struct rrdata::instance
& j
)
285 for(unsigned i
= 0; i
< 32; i
++) {
286 os
<< hexes
[j
.bytes
[i
] / 16] << hexes
[j
.bytes
[i
] % 16];
291 rrdata::instance
* rrdata::internal
;
294 //DBC0AB8CBAAC6ED4B7781E34057891E8B9D93AAE733DEF764C06957FF705DE00
295 //DBC0AB8CBAAC6ED4B7781E34057891E8B9D93AAE733DEF764C06957FF705DDF3