1370b324cSopenharmony_ci// UniqBlocks.cpp
2370b324cSopenharmony_ci
3370b324cSopenharmony_ci#include "StdAfx.h"
4370b324cSopenharmony_ci
5370b324cSopenharmony_ci#include <string.h>
6370b324cSopenharmony_ci
7370b324cSopenharmony_ci#include "UniqBlocks.h"
8370b324cSopenharmony_ci
9370b324cSopenharmony_ciunsigned CUniqBlocks::AddUniq(const Byte *data, size_t size)
10370b324cSopenharmony_ci{
11370b324cSopenharmony_ci  unsigned left = 0, right = Sorted.Size();
12370b324cSopenharmony_ci  while (left != right)
13370b324cSopenharmony_ci  {
14370b324cSopenharmony_ci    const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2);
15370b324cSopenharmony_ci    const unsigned index = Sorted[mid];
16370b324cSopenharmony_ci    const CByteBuffer &buf = Bufs[index];
17370b324cSopenharmony_ci    const size_t sizeMid = buf.Size();
18370b324cSopenharmony_ci    if (size < sizeMid)
19370b324cSopenharmony_ci      right = mid;
20370b324cSopenharmony_ci    else if (size > sizeMid)
21370b324cSopenharmony_ci      left = mid + 1;
22370b324cSopenharmony_ci    else
23370b324cSopenharmony_ci    {
24370b324cSopenharmony_ci      if (size == 0)
25370b324cSopenharmony_ci        return index;
26370b324cSopenharmony_ci      const int cmp = memcmp(data, buf, size);
27370b324cSopenharmony_ci      if (cmp == 0)
28370b324cSopenharmony_ci        return index;
29370b324cSopenharmony_ci      if (cmp < 0)
30370b324cSopenharmony_ci        right = mid;
31370b324cSopenharmony_ci      else
32370b324cSopenharmony_ci        left = mid + 1;
33370b324cSopenharmony_ci    }
34370b324cSopenharmony_ci  }
35370b324cSopenharmony_ci  unsigned index = Bufs.Size();
36370b324cSopenharmony_ci  Sorted.Insert(left, index);
37370b324cSopenharmony_ci  Bufs.AddNew().CopyFrom(data, size);
38370b324cSopenharmony_ci  return index;
39370b324cSopenharmony_ci}
40370b324cSopenharmony_ci
41370b324cSopenharmony_ciUInt64 CUniqBlocks::GetTotalSizeInBytes() const
42370b324cSopenharmony_ci{
43370b324cSopenharmony_ci  UInt64 size = 0;
44370b324cSopenharmony_ci  FOR_VECTOR (i, Bufs)
45370b324cSopenharmony_ci    size += Bufs[i].Size();
46370b324cSopenharmony_ci  return size;
47370b324cSopenharmony_ci}
48370b324cSopenharmony_ci
49370b324cSopenharmony_civoid CUniqBlocks::GetReverseMap()
50370b324cSopenharmony_ci{
51370b324cSopenharmony_ci  unsigned num = Sorted.Size();
52370b324cSopenharmony_ci  BufIndexToSortedIndex.ClearAndSetSize(num);
53370b324cSopenharmony_ci  unsigned *p = &BufIndexToSortedIndex[0];
54370b324cSopenharmony_ci  const unsigned *sorted = &Sorted[0];
55370b324cSopenharmony_ci  for (unsigned i = 0; i < num; i++)
56370b324cSopenharmony_ci    p[sorted[i]] = i;
57370b324cSopenharmony_ci}
58