Welcome to mirror list, hosted at ThFree Co, Russian Federation.

string_file.hpp « indexer - github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 2dce71f103bf2f32addbb037f20f49d8c8912970 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#pragma once

#include "../coding/file_writer.hpp"
#include "../coding/file_reader.hpp"

#include "../base/string_utils.hpp"

#include "../std/iterator_facade.hpp"
#include "../std/queue.hpp"
#include "../std/functional.hpp"
#include "../std/scoped_ptr.hpp"


class StringsFile
{
public:
  typedef buffer_vector<uint8_t, 32> ValueT;
  typedef uint32_t IdT;

  class StringT
  {
    strings::UniString m_name;
    ValueT m_val;

  public:
    StringT() {}
    StringT(strings::UniString const & name, signed char lang, ValueT const & val)
      : m_val(val)
    {
      m_name.reserve(name.size() + 1);
      m_name.push_back(static_cast<uint8_t>(lang));
      m_name.append(name.begin(), name.end());
    }

    uint32_t GetKeySize() const { return m_name.size(); }
    uint32_t const * GetKeyData() const { return m_name.data(); }

    strings::UniString const & GetString() const { return m_name; }

    template <class TCont> void SerializeValue(TCont & cont) const
    {
      cont.assign(m_val.begin(), m_val.end());
    }

    bool operator < (StringT const & name) const;
    bool operator == (StringT const & name) const;

    template <class TWriter> IdT Write(TWriter & writer) const;
    template <class TReader> void Read(TReader & src);

    void Swap(StringT & r)
    {
      m_name.swap(r.m_name);
      m_val.swap(r.m_val);
    }
  };

  class IteratorT : public iterator_facade<IteratorT, StringT, forward_traversal_tag, StringT>
  {
    StringsFile & m_file;
    bool m_end;

    bool IsEnd() const;
    inline bool IsValid() const { return (!m_end && !IsEnd()); }

  public:
    IteratorT(StringsFile & file, bool isEnd)
      : m_file(file), m_end(isEnd)
    {
      // Additional check in case for empty sequence.
      if (!m_end)
        m_end = IsEnd();
    }

    StringT dereference() const;
    bool equal(IteratorT const & r) const { return (m_end == r.m_end); }
    void increment();
  };

  StringsFile(string const & fPath);

  void EndAdding();
  void OpenForRead();

  /// @precondition Should be opened for writing.
  void AddString(StringT const & s);

  IteratorT Begin() { return IteratorT(*this, false); }
  IteratorT End() { return IteratorT(*this, true); }

private:
  scoped_ptr<FileWriter> m_writer;
  scoped_ptr<FileReader> m_reader;

  void Flush();
  bool PushNextValue(size_t i);

  vector<StringT> m_strings;
  // store start and end offsets of file portions
  vector<pair<uint64_t, uint64_t> > m_offsets;

  struct QValue
  {
    StringT m_string;
    size_t m_index;

    QValue(StringT const & s, size_t i) : m_string(s), m_index(i) {}

    inline bool operator > (QValue const & rhs) const { return !(m_string < rhs.m_string); }
  };

  priority_queue<QValue, vector<QValue>, greater<QValue> > m_queue;
};