summaryrefslogtreecommitdiff
path: root/src/shared/originconnection.cpp
blob: c1c096f06e07f3687845d8dd5929c90adfeb4056 (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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#include "originconnection.h"
#include "filesorigin.h"
#include "util.h"
#include <log.h>

namespace MOShared
{

using namespace MOBase;

OriginConnection::OriginConnection()
  : m_NextID(0)
{
}

std::pair<FilesOrigin&, bool> OriginConnection::getOrCreate(
  const std::wstring &originName, const std::wstring &directory, int priority,
  const boost::shared_ptr<FileRegister>& fileRegister,
  const boost::shared_ptr<OriginConnection>& originConnection,
  DirectoryStats& stats)
{
  std::unique_lock lock(m_Mutex);

  auto itor = m_OriginsNameMap.find(originName);

  if (itor == m_OriginsNameMap.end()) {
    FilesOrigin& origin = createOriginNoLock(
      originName, directory, priority, fileRegister, originConnection);

    return {origin, true};
  } else {
    FilesOrigin& origin = m_Origins[itor->second];
    lock.unlock();

    origin.enable(true, stats);
    return {origin, false};
  }
}

FilesOrigin& OriginConnection::createOrigin(
  const std::wstring &originName, const std::wstring &directory, int priority,
  boost::shared_ptr<FileRegister> fileRegister,
  boost::shared_ptr<OriginConnection> originConnection)
{
  std::scoped_lock lock(m_Mutex);

  return createOriginNoLock(
    originName, directory, priority, fileRegister, originConnection);
}

bool OriginConnection::exists(const std::wstring &name)
{
  std::scoped_lock lock(m_Mutex);
  return m_OriginsNameMap.find(name) != m_OriginsNameMap.end();
}

FilesOrigin& OriginConnection::getByID(OriginID ID)
{
  std::scoped_lock lock(m_Mutex);
  return m_Origins[ID];
}

const FilesOrigin* OriginConnection::findByID(OriginID ID) const
{
  std::scoped_lock lock(m_Mutex);

  auto itor = m_Origins.find(ID);

  if (itor == m_Origins.end()) {
    return nullptr;
  } else {
    return &itor->second;
  }
}

FilesOrigin& OriginConnection::getByName(const std::wstring &name)
{
  std::scoped_lock lock(m_Mutex);

  auto iter = m_OriginsNameMap.find(name);

  if (iter != m_OriginsNameMap.end()) {
    return m_Origins[iter->second];
  } else {
    std::ostringstream stream;
    stream << QObject::tr("invalid origin name: ").toStdString() << ToString(name, true);
    throw std::runtime_error(stream.str());
  }
}

void OriginConnection::changePriorityLookup(int oldPriority, int newPriority)
{
  std::scoped_lock lock(m_Mutex);

  auto iter = m_OriginsPriorityMap.find(oldPriority);

  if (iter != m_OriginsPriorityMap.end()) {
    OriginID idx = iter->second;
    m_OriginsPriorityMap.erase(iter);
    m_OriginsPriorityMap[newPriority] = idx;
  }
}

void OriginConnection::changeNameLookup(const std::wstring &oldName, const std::wstring &newName)
{
  std::scoped_lock lock(m_Mutex);

  auto iter = m_OriginsNameMap.find(oldName);

  if (iter != m_OriginsNameMap.end()) {
    OriginID idx = iter->second;
    m_OriginsNameMap.erase(iter);
    m_OriginsNameMap[newName] = idx;
  } else {
    log::error(QObject::tr("failed to change name lookup from {} to {}").toStdString(), oldName, newName);
  }
}

OriginID OriginConnection::createID()
{
  return m_NextID++;
}

FilesOrigin& OriginConnection::createOriginNoLock(
  const std::wstring &originName, const std::wstring &directory, int priority,
  boost::shared_ptr<FileRegister> fileRegister,
  boost::shared_ptr<OriginConnection> originConnection)
{
  OriginID newID = createID();

  auto itor = m_Origins.emplace(
    std::piecewise_construct,
    std::forward_as_tuple(newID),
    std::forward_as_tuple(
      newID, originName, directory, priority,
      fileRegister, originConnection))
    .first;

  m_OriginsNameMap.insert({originName, newID});
  m_OriginsPriorityMap.insert({priority, newID});

  return itor->second;
}

} // namespace