unite process/shared_memory datafacades into a single type using an allocator scheme

This commit is contained in:
Moritz Kobitzsch 2017-01-18 13:44:17 +01:00 committed by Patrick Niklaus
parent 75e0b5a5c4
commit b8beac2d00
11 changed files with 205 additions and 110 deletions

View File

@ -1,7 +1,8 @@
#ifndef OSRM_ENGINE_DATA_WATCHDOG_HPP
#define OSRM_ENGINE_DATA_WATCHDOG_HPP
#include "engine/datafacade/shared_memory_datafacade.hpp"
#include "engine/datafacade/contiguous_internalmem_datafacade.hpp"
#include "engine/datafacade/shared_memory_allocator.hpp"
#include "storage/shared_barriers.hpp"
#include "storage/shared_datatype.hpp"
@ -36,7 +37,8 @@ class DataWatchdog
auto shared_memory = makeSharedMemory(storage::CURRENT_REGION);
auto current = static_cast<storage::SharedDataTimestamp *>(shared_memory->Ptr());
facade = std::make_shared<datafacade::SharedMemoryDataFacade>(current->region);
facade = std::make_shared<datafacade::ContiguousInternalMemoryDataFacade>(
std::make_unique<datafacade::SharedMemoryAllocator>(current->region));
timestamp = current->timestamp;
}
@ -76,7 +78,8 @@ class DataWatchdog
if (timestamp != current->timestamp)
{
facade = std::make_shared<datafacade::SharedMemoryDataFacade>(current->region);
facade = std::make_shared<datafacade::ContiguousInternalMemoryDataFacade>(
std::make_unique<datafacade::SharedMemoryAllocator>(current->region));
timestamp = current->timestamp;
util::Log() << "updated facade to region "
<< storage::regionToString(current->region) << " with timestamp "
@ -91,7 +94,7 @@ class DataWatchdog
std::thread watcher;
bool active;
unsigned timestamp;
std::shared_ptr<datafacade::SharedMemoryDataFacade> facade;
std::shared_ptr<datafacade::ContiguousInternalMemoryDataFacade> facade;
};
}
}

View File

@ -0,0 +1,27 @@
#ifndef OSRM_ENGINE_DATAFACADE_CONTIGUOUS_BLOCK_ALLOCATOR_HPP_
#define OSRM_ENGINE_DATAFACADE_CONTIGUOUS_BLOCK_ALLOCATOR_HPP_
#include "storage/shared_datatype.hpp"
namespace osrm
{
namespace engine
{
namespace datafacade
{
class ContiguousBlockAllocator
{
public:
virtual ~ContiguousBlockAllocator() = default;
// interface to give access to the datafacades
virtual storage::DataLayout &GetLayout() = 0;
virtual char *GetMemory() = 0;
};
} // namespace datafacade
} // namespace engine
} // namespace osrm
#endif // OSRM_ENGINE_DATAFACADE_CONTIGUOUS_BLOCK_ALLOCATOR_HPP_

View File

@ -1,6 +1,7 @@
#ifndef CONTIGUOUS_INTERNALMEM_DATAFACADE_HPP
#define CONTIGUOUS_INTERNALMEM_DATAFACADE_HPP
#include "engine/datafacade/contiguous_block_allocator.hpp"
#include "engine/datafacade/datafacade_base.hpp"
#include "extractor/compressed_edge_container.hpp"
@ -52,7 +53,7 @@ namespace datafacade
* In this case "internal memory" refers to RAM - as opposed to "external memory",
* which usually refers to disk.
*/
class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
class ContiguousInternalMemoryDataFacade : public BaseDataFacade
{
private:
using super = BaseDataFacade;
@ -115,6 +116,9 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
std::shared_ptr<util::RangeTable<16, true>> m_bearing_ranges_table;
util::ShM<DiscreteBearing, true>::vector m_bearing_values_table;
// allocator that keeps the allocation data
std::unique_ptr<ContiguousBlockAllocator> allocator;
void InitializeChecksumPointer(storage::DataLayout &data_layout, char *memory_block)
{
m_check_sum =
@ -397,7 +401,6 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
m_entry_class_table = std::move(entry_class_table);
}
public:
void InitializeInternalPointers(storage::DataLayout &data_layout, char *memory_block)
{
InitializeGraphPointer(data_layout, memory_block);
@ -414,6 +417,15 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
InitializeIntersectionClassPointers(data_layout, memory_block);
}
public:
// allows switching between process_memory/shared_memory datafacade, based on the type of
// allocator
ContiguousInternalMemoryDataFacade(std::unique_ptr<ContiguousBlockAllocator> allocator_)
: allocator(std::move(allocator_))
{
InitializeInternalPointers(allocator->GetLayout(), allocator->GetMemory());
}
// search graph access
unsigned GetNumberOfNodes() const override final { return m_query_graph->GetNumberOfNodes(); }

View File

@ -0,0 +1,42 @@
#ifndef OSRM_ENGINE_DATAFACADE_PROCESS_MEMORY_ALLOCATOR_HPP_
#define OSRM_ENGINE_DATAFACADE_PROCESS_MEMORY_ALLOCATOR_HPP_
#include "storage/storage_config.hpp"
#include "engine/datafacade/contiguous_block_allocator.hpp"
#include <memory>
namespace osrm
{
namespace engine
{
namespace datafacade
{
/**
* This allocator uses a process-local memory block to load
* data into. The structure and layout is the same as when using
* shared memory.
* This class holds a unique_ptr to the memory block, so it
* is auto-freed upon destruction.
*/
class ProcessMemoryAllocator : public ContiguousBlockAllocator
{
public:
explicit ProcessMemoryAllocator(const storage::StorageConfig &config);
~ProcessMemoryAllocator() override final;
// interface to give access to the datafacades
storage::DataLayout &GetLayout() override final;
char *GetMemory() override final;
private:
std::unique_ptr<char[]> internal_memory;
std::unique_ptr<storage::DataLayout> internal_layout;
};
} // namespace datafacade
} // namespace engine
} // namespace osrm
#endif // OSRM_ENGINE_DATAFACADE_PROCESS_MEMORY_ALLOCATOR_HPP_

View File

@ -1,52 +0,0 @@
#ifndef PROCESS_MEMORY_DATAFACADE_HPP
#define PROCESS_MEMORY_DATAFACADE_HPP
// implements all data storage when shared memory is _NOT_ used
#include "storage/storage.hpp"
#include "engine/datafacade/contiguous_internalmem_datafacade_base.hpp"
namespace osrm
{
namespace engine
{
namespace datafacade
{
/**
* This datafacade uses a process-local memory block to load
* data into. The structure and layout is the same as when using
* shared memory, so this class, and the SharedMemoryDataFacade both
* share a common base.
* This class holds a unique_ptr to the memory block, so it
* is auto-freed upon destruction.
*/
class ProcessMemoryDataFacade final : public ContiguousInternalMemoryDataFacadeBase
{
private:
std::unique_ptr<char[]> internal_memory;
std::unique_ptr<storage::DataLayout> internal_layout;
public:
explicit ProcessMemoryDataFacade(const storage::StorageConfig &config)
{
storage::Storage storage(config);
// Calculate the layout/size of the memory block
internal_layout = std::make_unique<storage::DataLayout>();
storage.PopulateLayout(*internal_layout);
// Allocate the memory block, then load data from files into it
internal_memory = std::make_unique<char[]>(internal_layout->GetSizeOfLayout());
storage.PopulateData(*internal_layout, internal_memory.get());
// Adjust all the private m_* members to point to the right places
InitializeInternalPointers(*internal_layout.get(), internal_memory.get());
}
};
}
}
}
#endif // PROCESS_MEMORY_DATAFACADE_HPP

View File

@ -0,0 +1,41 @@
#ifndef OSRM_ENGINE_DATAFACADE_SHARED_MEMORY_ALLOCATOR_HPP_
#define OSRM_ENGINE_DATAFACADE_SHARED_MEMORY_ALLOCATOR_HPP_
#include "engine/datafacade/contiguous_block_allocator.hpp"
#include "storage/shared_datatype.hpp"
#include "storage/shared_memory.hpp"
#include <memory>
namespace osrm
{
namespace engine
{
namespace datafacade
{
/**
* This allocator uses an IPC shared memory block as the data location.
* Many SharedMemoryDataFacade objects can be created that point to the same shared
* memory block.
*/
class SharedMemoryAllocator : public ContiguousBlockAllocator
{
public:
explicit SharedMemoryAllocator(storage::SharedDataType data_region);
~SharedMemoryAllocator() override final;
// interface to give access to the datafacades
storage::DataLayout &GetLayout() override final;
char *GetMemory() override final;
private:
std::unique_ptr<storage::SharedMemory> m_large_memory;
};
} // namespace datafacade
} // namespace engine
} // namespace osrm
#endif // OSRM_ENGINE_DATAFACADE_SHARED_MEMORY_ALLOCATOR_HPP_

View File

@ -1,49 +0,0 @@
#ifndef SHARED_MEMORY_DATAFACADE_HPP
#define SHARED_MEMORY_DATAFACADE_HPP
// implements all data storage when shared memory _IS_ used
#include "storage/shared_barriers.hpp"
#include "storage/shared_datatype.hpp"
#include "storage/shared_memory.hpp"
#include "engine/datafacade/contiguous_internalmem_datafacade_base.hpp"
namespace osrm
{
namespace engine
{
namespace datafacade
{
/**
* This datafacade uses an IPC shared memory block as the data location.
* Many SharedMemoryDataFacade objects can be created that point to the same shared
* memory block.
*/
class SharedMemoryDataFacade : public ContiguousInternalMemoryDataFacadeBase
{
protected:
std::unique_ptr<storage::SharedMemory> m_large_memory;
storage::SharedDataType data_region;
SharedMemoryDataFacade() {}
public:
SharedMemoryDataFacade(storage::SharedDataType data_region) : data_region(data_region)
{
util::Log(logDEBUG) << "Loading new data for region " << regionToString(data_region);
BOOST_ASSERT(storage::SharedMemory::RegionExists(data_region));
m_large_memory = storage::makeSharedMemory(data_region);
InitializeInternalPointers(*reinterpret_cast<storage::DataLayout *>(m_large_memory->Ptr()),
reinterpret_cast<char *>(m_large_memory->Ptr()) +
sizeof(storage::DataLayout));
}
};
}
}
}
#endif // SHARED_MEMORY_DATAFACADE_HPP

View File

@ -8,6 +8,7 @@
#include "engine/api/tile_parameters.hpp"
#include "engine/api/trip_parameters.hpp"
#include "engine/data_watchdog.hpp"
#include "engine/datafacade/contiguous_block_allocator.hpp"
#include "engine/datafacade/datafacade_base.hpp"
#include "engine/engine_config.hpp"
#include "engine/plugins/match.hpp"

View File

@ -0,0 +1,33 @@
#include "engine/datafacade/process_memory_allocator.hpp"
#include "storage/storage.hpp"
#include "boost/assert.hpp"
namespace osrm
{
namespace engine
{
namespace datafacade
{
ProcessMemoryAllocator::ProcessMemoryAllocator(const storage::StorageConfig &config)
{
storage::Storage storage(config);
// Calculate the layout/size of the memory block
internal_layout = std::make_unique<storage::DataLayout>();
storage.PopulateLayout(*internal_layout);
// Allocate the memory block, then load data from files into it
internal_memory = std::make_unique<char[]>(internal_layout->GetSizeOfLayout());
storage.PopulateData(*internal_layout, internal_memory.get());
}
ProcessMemoryAllocator::~ProcessMemoryAllocator() {}
storage::DataLayout &ProcessMemoryAllocator::GetLayout() { return *internal_layout.get(); }
char *ProcessMemoryAllocator::GetMemory() { return internal_memory.get(); }
} // namespace datafacade
} // namespace engine
} // namespace osrm

View File

@ -0,0 +1,34 @@
#include "engine/datafacade/shared_memory_allocator.hpp"
#include "util/log.hpp"
#include "boost/assert.hpp"
namespace osrm
{
namespace engine
{
namespace datafacade
{
SharedMemoryAllocator::SharedMemoryAllocator(storage::SharedDataType data_region)
{
util::Log(logDEBUG) << "Loading new data for region " << regionToString(data_region);
BOOST_ASSERT(storage::SharedMemory::RegionExists(data_region));
m_large_memory = storage::makeSharedMemory(data_region);
}
SharedMemoryAllocator::~SharedMemoryAllocator() {}
storage::DataLayout &SharedMemoryAllocator::GetLayout()
{
return *reinterpret_cast<storage::DataLayout *>(m_large_memory->Ptr());
}
char *SharedMemoryAllocator::GetMemory()
{
return reinterpret_cast<char *>(m_large_memory->Ptr()) + sizeof(storage::DataLayout);
}
} // namespace datafacade
} // namespace engine
} // namespace osrm

View File

@ -3,8 +3,8 @@
#include "engine/engine_config.hpp"
#include "engine/status.hpp"
#include "engine/datafacade/process_memory_datafacade.hpp"
#include "engine/datafacade/shared_memory_datafacade.hpp"
#include "engine/datafacade/contiguous_internalmem_datafacade.hpp"
#include "engine/datafacade/process_memory_allocator.hpp"
#include "storage/shared_barriers.hpp"
#include "util/log.hpp"
@ -80,8 +80,11 @@ Engine::Engine(const EngineConfig &config)
{
throw util::exception("Invalid file paths given!" + SOURCE_REF);
}
auto allocator =
std::make_unique<datafacade::ProcessMemoryAllocator>(config.storage_config);
immutable_data_facade =
std::make_shared<const datafacade::ProcessMemoryDataFacade>(config.storage_config);
std::make_shared<const datafacade::ContiguousInternalMemoryDataFacade>(
std::move(allocator));
}
}