Compute ambient coeffects and write to coeffects local
[hiphop-php.git] / hphp / runtime / vm / litstr-repo-proxy.cpp
blob7fffb66b4167476ec49368a46cc4640d6dcf624c
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-present Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
17 #include "hphp/runtime/vm/unit.h"
18 #include "hphp/runtime/vm/repo.h"
20 namespace HPHP {
22 std::atomic_int LitstrRepoProxy::s_loadedRepoId{RepoIdInvalid};
24 LitstrRepoProxy::~LitstrRepoProxy() {
25 if (!m_inited) return;
26 m_litstrLoader.~GetOneLitstrStmt();
29 void LitstrRepoProxy::createSchema(int repoId, RepoTxn& txn) {
30 auto insertQuery = folly::sformat(
31 "CREATE TABLE {} (litstrId INTEGER PRIMARY KEY, litstr TEXT);",
32 m_repo.table(repoId, "Litstr"));
33 txn.exec(insertQuery);
36 void LitstrRepoProxy::load(bool lazy) {
37 assertx(s_loadedRepoId.load(std::memory_order_relaxed) == RepoIdInvalid);
38 for (int repoId = m_repo.numOpenRepos() - 1; repoId >= 0; --repoId) {
39 // Return success on the first loaded repo. In the case of an error we
40 // continue on to the next repo.
41 GetLitstrCountStmt stmt{m_repo, repoId};
42 auto const maxId = stmt.get();
43 if (maxId <= 0) continue;
45 auto& table = LitstrTable::get();
46 assertx(table.numLitstrs() == 0);
47 NamedEntityPairTable namedInfo;
48 namedInfo.resize(maxId + 1, LowStringPtr{nullptr});
49 table.setNamedEntityPairTable(std::move(namedInfo));
50 s_loadedRepoId.store(repoId, std::memory_order_release);
51 if (!lazy) loadAll();
52 break;
54 // No repos were loadable. This is normal for non-repo-authoritative repos.
57 void LitstrRepoProxy::loadAll() {
58 auto const repoId = s_loadedRepoId.load(std::memory_order_acquire);
59 assertx(repoId != RepoIdInvalid);
60 GetLitstrsStmt stmt{m_repo, repoId};
61 DEBUG_ONLY auto const ret = stmt.get();
62 assertx(ret == RepoStatus::success);
65 StringData* LitstrRepoProxy::loadOne(Id id) {
66 if (!m_inited) {
67 auto const repoId = s_loadedRepoId.load(std::memory_order_acquire);
68 assertx(repoId != RepoIdInvalid);
69 new (&m_litstrLoader) GetOneLitstrStmt(m_repo, repoId);
70 m_inited = true;
72 auto const ret = m_litstrLoader.getOne(id);
73 LitstrTable::get().setLitstr(id, ret);
74 return ret;
77 void LitstrRepoProxy::InsertLitstrStmt::insert(RepoTxn& txn,
78 Id litstrId,
79 const StringData* litstr) {
80 if (!prepared()) {
81 auto insertQuery = folly::sformat(
82 "INSERT INTO {} VALUES(@litstrId, @litstr);",
83 m_repo.table(m_repoId, "Litstr"));
84 txn.prepare(*this, insertQuery);
86 RepoTxnQuery query(txn, *this);
87 query.bindInt64("@litstrId", litstrId);
88 query.bindStaticString("@litstr", litstr);
89 query.exec();
92 int LitstrRepoProxy::GetLitstrCountStmt::get() {
93 int count = -1;
94 try {
95 if (!prepared()) {
96 auto selectQuery = folly::sformat("SELECT max(litstrId) FROM {};",
97 m_repo.table(m_repoId, "Litstr"));
98 prepare(selectQuery);
100 RepoQuery query(*this);
101 query.step();
102 if (query.row()) query.getInt(0, count);
103 } catch (RepoExc& re) {
104 return -1;
106 return count;
109 RepoStatus LitstrRepoProxy::GetLitstrsStmt::get() {
110 // load all literals in the repo, after lazy loading.
111 assertx(s_loadedRepoId.load(std::memory_order_acquire) == m_repoId);
113 auto& table = LitstrTable::get();
115 try {
116 if (!prepared()) {
117 auto selectQuery = folly::sformat(
118 "SELECT litstrId,litstr FROM {} ORDER BY litstrId;",
119 m_repo.table(m_repoId, "Litstr"));
120 prepare(selectQuery);
122 RepoQuery query(*this);
123 int index = 1;
124 do {
125 query.step();
126 if (query.row()) {
127 int litstrId;
128 query.getInt(0, litstrId);
129 always_assert(
130 litstrId == index++ && "LitstrId needs to be from 1 to N"
132 StringData* litstr; /**/ query.getStaticString(1, litstr);
133 table.setLitstr(litstrId, litstr);
135 } while (!query.done());
136 } catch (RepoExc& re) {
137 return RepoStatus::error;
139 return RepoStatus::success;
142 StringData* LitstrRepoProxy::GetOneLitstrStmt::getOne(int litstrId) {
143 try {
144 if (!prepared()) {
145 auto selectQuery = folly::sformat(
146 "SELECT litstrid,litstr FROM {} WHERE litstrId = @litstrId;",
147 m_repo.table(m_repoId, "Litstr"));
148 prepare(selectQuery);
150 RepoQuery query(*this);
151 query.bindInt("@litstrId", litstrId);
152 query.step();
153 StringData* litstr = nullptr;
154 if (query.row()) {
155 int index = 0;
156 query.getInt(0, index);
157 assert(litstrId == index);
158 query.getStaticString(1, litstr);
159 return litstr;
161 } catch (RepoExc& re) {
163 return nullptr;