31
31
#include " utils/directory_utils.hpp"
32
32
#include " utils/memory.hpp"
33
33
#include " utils/misc.hpp"
34
- #include " utils/utf8_path.hpp"
35
34
36
35
#include " ApplicationServerHelper.h"
37
36
#include " IResearchAttributes.h"
@@ -245,43 +244,6 @@ inline arangodb::FlushFeature* getFlushFeature() noexcept {
245
244
return arangodb::iresearch::getFeature<arangodb::FlushFeature>(" Flush" );
246
245
}
247
246
248
- // //////////////////////////////////////////////////////////////////////////////
249
- // / @brief construct an absolute path from the IResearchViewMeta configuration
250
- // //////////////////////////////////////////////////////////////////////////////
251
- bool appendAbsolutePersistedDataPath (
252
- std::string& buf,
253
- arangodb::iresearch::IResearchView const & view,
254
- arangodb::iresearch::IResearchViewMeta const & meta
255
- ) {
256
- auto & path = meta._dataPath ;
257
-
258
- if (path.empty ()) {
259
- return false ; // empty data path should have been set to a default value
260
- }
261
-
262
- if (TRI_PathIsAbsolute (path)) {
263
- buf = path;
264
-
265
- return true ;
266
- }
267
-
268
- auto * feature = arangodb::iresearch::getFeature<arangodb::DatabasePathFeature>(" DatabasePath" );
269
-
270
- if (!feature) {
271
- return false ;
272
- }
273
-
274
- // get base path from DatabaseServerFeature (similar to MMFilesEngine)
275
- irs::utf8_path absPath (feature->directory ());
276
- static std::string subPath (" databases" );
277
-
278
- absPath/=subPath;
279
- absPath/=path;
280
- buf = absPath.utf8 ();
281
-
282
- return true ;
283
- }
284
-
285
247
// //////////////////////////////////////////////////////////////////////////////
286
248
// / @brief append link removal directives to the builder and return success
287
249
// //////////////////////////////////////////////////////////////////////////////
@@ -870,16 +832,22 @@ IResearchView::MemoryStore::MemoryStore() {
870
832
_reader = irs::directory_reader::open (*_directory); // open after 'commit' for valid 'store'
871
833
}
872
834
835
+ IResearchView::PersistedStore::PersistedStore (irs::utf8_path&& path)
836
+ : _path(std::move(path)) {
837
+ }
838
+
873
839
IResearchView::IResearchView (
874
840
arangodb::LogicalView* view,
875
- arangodb::velocypack::Slice const & info
841
+ arangodb::velocypack::Slice const & info,
842
+ irs::utf8_path&& persistedPath
876
843
) : ViewImplementation(view, info),
877
844
FlushTransaction(toString(*this )),
878
845
_asyncMetaRevision(1 ),
879
846
_asyncSelf(irs::memory::make_unique<AsyncSelf>(this )),
880
847
_asyncTerminate(false ),
881
848
_memoryNode(&_memoryNodes[0 ]), // set current memory node (arbitrarily 0)
882
849
_toFlush(&_memoryNodes[1 ]), // set flush-pending memory node (not same as _memoryNode)
850
+ _storePersisted(std::move(persistedPath)),
883
851
_threadPool(0 , 0 ), // 0 == create pool with no threads, i.e. not running anything
884
852
_inRecovery(false ) {
885
853
// set up in-recovery insertion hooks
@@ -1207,7 +1175,11 @@ void IResearchView::drop() {
1207
1175
_storePersisted._directory .reset ();
1208
1176
}
1209
1177
1210
- if (!TRI_IsDirectory (_meta._dataPath .c_str ()) || TRI_ERROR_NO_ERROR == TRI_RemoveDirectory (_meta._dataPath .c_str ())) {
1178
+ bool exists;
1179
+
1180
+ // remove persisted data store directory if present
1181
+ if (_storePersisted._path .exists_directory (exists)
1182
+ && (!exists || _storePersisted._path .remove ())) {
1211
1183
return ; // success
1212
1184
}
1213
1185
} catch (std::exception const & e) {
@@ -1690,12 +1662,40 @@ arangodb::Result IResearchView::link(
1690
1662
arangodb::velocypack::Slice const & info,
1691
1663
bool isNew
1692
1664
) {
1693
- PTR_NAMED (IResearchView, ptr, view, info);
1665
+ if (!view) {
1666
+ LOG_TOPIC (WARN, IResearchFeature::IRESEARCH)
1667
+ << " invalid LogicalView argument while constructing IResearch view" ;
1668
+ return nullptr ;
1669
+ }
1670
+
1671
+ auto * feature =
1672
+ arangodb::iresearch::getFeature<arangodb::DatabasePathFeature>(" DatabasePath" );
1673
+
1674
+ if (!feature) {
1675
+ LOG_TOPIC (WARN, IResearchFeature::IRESEARCH)
1676
+ << " failure to find feature 'DatabasePath' while constructing IResearch view '" << view->id () << " '" ;
1677
+
1678
+ return nullptr ;
1679
+ }
1680
+
1681
+ // get base path from DatabaseServerFeature (similar to MMFilesEngine)
1682
+ // the path is hardcoded to reside under:
1683
+ // <DatabasePath>/<IResearchView::type()>-<view id>
1684
+ // similar to the data path calculation for collections
1685
+ irs::utf8_path dataPath (feature->directory ());
1686
+ static std::string subPath (" databases" );
1687
+
1688
+ dataPath /= subPath;
1689
+ dataPath /= arangodb::iresearch::IResearchView::type ();
1690
+ dataPath += " -" ;
1691
+ dataPath += std::to_string (view->id ());
1692
+
1693
+ PTR_NAMED (IResearchView, ptr, view, info, std::move (dataPath));
1694
1694
auto & impl = reinterpret_cast <IResearchView&>(*ptr);
1695
1695
auto & json = info.isNone () ? emptyObjectSlice () : info; // if no 'info' then assume defaults
1696
1696
std::string error;
1697
1697
1698
- if (!view || ! impl._meta .init (json, error, *view )) {
1698
+ if (!impl._meta .init (json, error)) {
1699
1699
LOG_TOPIC (WARN, iresearch::IResearchFeature::IRESEARCH)
1700
1700
<< " failed to initialize iResearch view from definition, error: " << error;
1701
1701
@@ -1727,6 +1727,7 @@ size_t IResearchView::memory() const {
1727
1727
1728
1728
if (_storePersisted) {
1729
1729
size += directoryMemory (*(_storePersisted._directory ), id ());
1730
+ size += _storePersisted._path .native ().size () * sizeof (irs::utf8_path::native_char_t );
1730
1731
}
1731
1732
1732
1733
return size;
@@ -1750,14 +1751,12 @@ void IResearchView::open() {
1750
1751
return ; // view already open
1751
1752
}
1752
1753
1753
- std::string absoluteDataPath;
1754
-
1755
1754
try {
1756
1755
auto format = irs::formats::get (IRESEARCH_STORE_FORMAT);
1757
1756
1758
- if (format && appendAbsolutePersistedDataPath (absoluteDataPath, * this , _meta) ) {
1757
+ if (format) {
1759
1758
_storePersisted._directory =
1760
- irs::directory::make<irs::mmap_directory>(absoluteDataPath );
1759
+ irs::directory::make<irs::mmap_directory>(_storePersisted. _path . utf8 () );
1761
1760
1762
1761
if (_storePersisted._directory ) {
1763
1762
// create writer before reader to ensure data directory is present
@@ -1800,10 +1799,10 @@ void IResearchView::open() {
1800
1799
}
1801
1800
1802
1801
LOG_TOPIC (WARN, iresearch::IResearchFeature::IRESEARCH)
1803
- << " failed to open iResearch view '" << id () << " ' at: " << absoluteDataPath ;
1802
+ << " failed to open IResearch view '" << name () << " ' at: " << _storePersisted. _path . utf8 () ;
1804
1803
1805
1804
throw std::runtime_error (
1806
- std::string (" failed to open iResearch view '" ) + std::to_string ( id ()) + " ' at: " + absoluteDataPath
1805
+ std::string (" failed to open iResearch view '" ) + name () + " ' at: " + _storePersisted. _path . utf8 ()
1807
1806
);
1808
1807
}
1809
1808
@@ -2052,7 +2051,7 @@ arangodb::Result IResearchView::updateProperties(
2052
2051
2053
2052
auto & initialMeta = partialUpdate ? _meta : IResearchViewMeta::DEFAULT ();
2054
2053
2055
- if (!meta.init (slice, error, *_logicalView, initialMeta, &mask)) {
2054
+ if (!meta.init (slice, error, initialMeta, &mask)) {
2056
2055
return arangodb::Result (TRI_ERROR_BAD_PARAMETER, std::move (error));
2057
2056
}
2058
2057
@@ -2123,75 +2122,6 @@ arangodb::Result IResearchView::updateProperties(
2123
2122
// reset non-updatable values to match current meta
2124
2123
meta._collections = _meta._collections ;
2125
2124
2126
- // do not modify data path if not changes since will cause lock obtain failure
2127
- mask._dataPath = mask._dataPath && _meta._dataPath != meta._dataPath ;
2128
-
2129
- DataStore storePersisted; // renamed persisted data store
2130
- std::string srcDataPath = _meta._dataPath ;
2131
- char const * dropDataPath = nullptr ;
2132
-
2133
- // copy directory to new location
2134
- if (mask._dataPath ) {
2135
- std::string absoluteDataPath;
2136
-
2137
- if (!appendAbsolutePersistedDataPath (absoluteDataPath, *this , meta)) {
2138
- return arangodb::Result (
2139
- TRI_ERROR_BAD_PARAMETER,
2140
- std::string (" error generating absolute path for iResearch view '" ) + std::to_string (id ()) + " ' data path '" + meta._dataPath + " '"
2141
- );
2142
- }
2143
-
2144
- auto res = createPersistedDataDirectory (
2145
- storePersisted._directory ,
2146
- storePersisted._writer ,
2147
- absoluteDataPath,
2148
- _storePersisted._reader , // reader from the original persisted data store
2149
- id ()
2150
- );
2151
-
2152
- if (!res.ok ()) {
2153
- return res;
2154
- }
2155
-
2156
- try {
2157
- storePersisted._reader = irs::directory_reader::open (*(storePersisted._directory ));
2158
- storePersisted._segmentCount += storePersisted._reader .size (); // add commited segments (previously had 0)
2159
- dropDataPath = _storePersisted ? srcDataPath.c_str () : nullptr ;
2160
- } catch (std::exception const & e) {
2161
- LOG_TOPIC (WARN, iresearch::IResearchFeature::IRESEARCH)
2162
- << " caught exception while opening iResearch view '" << id ()
2163
- << " ' data path '" + meta._dataPath + " ': " << e.what ();
2164
- IR_LOG_EXCEPTION ();
2165
- return arangodb::Result (
2166
- TRI_ERROR_BAD_PARAMETER,
2167
- std::string (" error opening iResearch view '" ) + std::to_string (id ()) + " ' data path '" + meta._dataPath + " '"
2168
- );
2169
- } catch (...) {
2170
- LOG_TOPIC (WARN, iresearch::IResearchFeature::IRESEARCH)
2171
- << " caught exception while opening iResearch view '" << id () << " ' data path '" + meta._dataPath + " '" ;
2172
- IR_LOG_EXCEPTION ();
2173
- return arangodb::Result (
2174
- TRI_ERROR_BAD_PARAMETER,
2175
- std::string (" error opening iResearch view '" ) + std::to_string (id ()) + " ' data path '" + meta._dataPath + " '"
2176
- );
2177
- }
2178
-
2179
- if (!storePersisted._reader ) {
2180
- LOG_TOPIC (WARN, iresearch::IResearchFeature::IRESEARCH)
2181
- << " error while opening reader for iResearch view '" << id () << " ' data path '" + meta._dataPath + " '" ;
2182
- return arangodb::Result (
2183
- TRI_ERROR_BAD_PARAMETER,
2184
- std::string (" error opening reader for iResearch view '" ) + std::to_string (id ()) + " ' data path '" + meta._dataPath + " '"
2185
- );
2186
- }
2187
- }
2188
-
2189
- _meta = std::move (meta);
2190
-
2191
- if (mask._dataPath ) {
2192
- _storePersisted = std::move (storePersisted);
2193
- }
2194
-
2195
2125
if (mask._threadsMaxIdle ) {
2196
2126
_threadPool.max_idle (meta._threadsMaxIdle );
2197
2127
}
@@ -2205,9 +2135,7 @@ arangodb::Result IResearchView::updateProperties(
2205
2135
_asyncCondition.notify_all (); // trigger reload of timeout settings for async jobs
2206
2136
}
2207
2137
2208
- if (dropDataPath) {
2209
- res = TRI_RemoveDirectory (dropDataPath); // ignore error (only done to tidy-up filesystem)
2210
- }
2138
+ _meta = std::move (meta);
2211
2139
}
2212
2140
2213
2141
std::unordered_set<TRI_voc_cid_t> collections;
@@ -2373,4 +2301,4 @@ NS_END // arangodb
2373
2301
2374
2302
// -----------------------------------------------------------------------------
2375
2303
// --SECTION-- END-OF-FILE
2376
- // -----------------------------------------------------------------------------
2304
+ // -----------------------------------------------------------------------------
0 commit comments