version 2.3.0_beta

optimize PIChunkStream::readAll()
optimize PIEvaluator
This commit is contained in:
2020-08-24 02:08:23 +03:00
parent 6b70045914
commit f033119a8b
4 changed files with 194 additions and 166 deletions

View File

@@ -80,11 +80,36 @@ int PIChunkStream::read() {
}
int PIChunkStream::peekVInt(Version version_, PIByteArray * data_, int pos, PIByteArray & hdr, uint & ret) {
switch (version_) {
case Version_1:
memcpy(&ret, data_->data(pos), 4);
return 4;
case Version_2: {
hdr.resize(4);
hdr.fill(uchar(0));
memcpy(hdr.data(), data_->data(pos), piMini(4, data_->size_s() - pos));
uchar hsz = 0;
ret = readVInt(hdr, &hsz);
return hsz;
}
default: break;
}
return 0;
}
void PIChunkStream::readAll() {
data_map.clear();
while (!atEnd()) {
read();
data_map[last_id] = last_data;
if (!data_) return;
int pos = 0, sz = data_->size_s();
uint csz = 0, cid = 0;
PIByteArray hdr;
while (pos < sz) {
pos += peekVInt((Version)version_, data_, pos, hdr, cid);
pos += peekVInt((Version)version_, data_, pos, hdr, csz);
data_map[cid] = PIPair<int, int>(pos, csz);
pos += csz;
}
}
@@ -111,7 +136,7 @@ void PIChunkStream::_init() {
}
uint PIChunkStream::readVInt(PIByteArray & s) {
uint PIChunkStream::readVInt(PIByteArray & s, uchar * bytes_cnt) {
if (s.isEmpty()) return 0;
uchar bytes[4]; s >> bytes[0];
uchar abc = 0;
@@ -122,6 +147,7 @@ uint PIChunkStream::readVInt(PIByteArray & s) {
s >> bytes[abc + 1];
} else break;
}
if (bytes_cnt) *bytes_cnt = (abc + 1);
uint ret = 0;
for (int i = 0; i <= abc; ++i) {
ret += (bytes[i] << (8 * ((int)abc - i)));

View File

@@ -79,11 +79,11 @@ public:
//! Returns stream version
Version version() const {return (Version)version_;}
//! Read one chunk from stream and returns its ID
int read();
//! Read all chunks from stream
//! Read all chunks from stream. This function just index input data
void readAll();
//! Returns last readed chunk ID
@@ -100,7 +100,9 @@ public:
//! Place value of chunk with id \"id\" into \"v\". You should call \a readAll() before using this function!
template <typename T>
const PIChunkStream & get(int id, T & v) const {
PIByteArray ba = data_map.value(id);
PIPair<int, int> pos = data_map.value(id);
if (pos.first < 0 || pos.second == 0) return *this;
PIByteArray ba(data_->data(pos.first), pos.second);
if (!ba.isEmpty())
ba >> v;
return *this;
@@ -109,13 +111,14 @@ public:
private:
void _init();
static uint readVInt(PIByteArray & s);
static uint readVInt(PIByteArray & s, uchar * bytes = 0);
static void writeVInt(PIByteArray & s, uint val);
static int peekVInt(Version version_, PIByteArray * data_, int pos, PIByteArray & hdr, uint & ret);
int last_id;
uchar version_;
PIByteArray * data_, last_data, tmp_data;
PIMap<int, PIByteArray> data_map;
PIMap<int, PIPair<int, int>> data_map;
template <typename T> friend PIChunkStream & operator <<(PIChunkStream & s, const PIChunkStream::Chunk<T> & c);
template <typename T> friend PIChunkStream & operator <<(PIChunkStream & s, const PIChunkStream::ChunkConst<T> & c);