Beispiel #1
0
void BlockManager::CreateNew(offset_type blocksize)
{
    m_pFile->Seek(offset_type(0), IFile::S_Begin);

    m_pFile->Write(&m_Header, offset_type(sizeof(m_Header)));
    m_pFile->ReserveSpace(offset_type(sizeof(m_Header)));
}
Beispiel #2
0
void BlockManager::FlushHeader()
{
    CheckHeader();
    m_pFile->Seek(offset_type(0), IFile::S_Begin);

    m_pFile->Write(&m_Header, offset_type(sizeof(m_Header)));
}
Beispiel #3
0
int main()
{
    _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
    IFile::OpenMode mode = IFile::O_Truncate;
    IFile *pFile = OpenDiskFile("test.pkg", mode);
    BlockManager* pMgr = new BlockManager(pFile, mode==IFile::O_Truncate, offset_type(1024));
    BlockFS *pFS = new BlockFS(pMgr, mode);

    pFS->AddFile("test123", "test123", offset_type(sizeof("test123")));
    pFS->AddFile("test1234", "test1234", offset_type(sizeof("test1234")));

    IFile* pf1 = pFS->OpenFileInPackage("test123");
    IFile* pf2 = pFS->OpenFileInPackage("test1234");
    assert(pf1->GetSize()==offset_type(sizeof("test123")));
    assert(pf2->GetSize()==offset_type(sizeof("test1234")));
    char buffer[16];
    offset_type r = pf1->Read(buffer, offset_type(sizeof(buffer)));
    assert(r == offset_type(sizeof("test123")));
    assert(strcmp(buffer, "test123")==0);

    r = pf2->Read(buffer, offset_type(sizeof(buffer)));
    assert(r == offset_type(sizeof("test1234")));
    assert(strcmp(buffer, "test1234")==0);

    delete pf1;
    delete pf2;

    pFS->RemoveFile("test123");
    pFS->RemoveFile("test1234");
    pFS->AddFile("test1234", "test1234", offset_type(sizeof("test1234")));

    delete pFS;
    delete pMgr;
    delete pFile;
}
Beispiel #4
0
BlockManager::BlockManager(IFile* pFile, bool truncate, offset_type blocksize)
    :m_pFile(pFile), m_Header(blocksize, offset_type(-1), offset_type(0)), m_pLock(new FileLock)
{
    if(truncate)
    {
        CreateNew(blocksize);
    }
    else
    {
        LoadExist(blocksize);
    }
}
Beispiel #5
0
void BlockManager::WriteEmptyBlockHeader( offset_type blockid, offset_type header )
{
    assert(header<blockid&&"Wrong Empty Block header");
    assert(blockid < m_Header.Blocks && "out of range");
    m_pFile->Seek(CalcOffset(blockid), IFile::S_Begin);
    m_pFile->Write(&header, offset_type(sizeof(header)));
}
Beispiel #6
0
void BlockManager::ReadEmptyBlockHeader( offset_type blockid, offset_type &header )
{
    //FileAutoLock lock(m_pLock);
    assert(blockid < m_Header.Blocks && "out of range");
    m_pFile->Seek(CalcOffset(blockid), IFile::S_Begin);
    m_pFile->Read(&header, offset_type(sizeof(header)));
}
Beispiel #7
0
wbtl_file::offset_type wbtl_file::get_next_write_block()
{
    // mapping_lock has to be aquired by caller
    sortseq::iterator space =
        std::find_if(free_space.begin(), free_space.end(),
                     bind2nd(FirstFit(), write_block_size) _STXXL_FORCE_SEQUENTIAL);

    if (space != free_space.end())
    {
        offset_type region_pos = (*space).first;
        offset_type region_size = (*space).second;
        free_space.erase(space);
        if (region_size > write_block_size)
            free_space[region_pos + write_block_size] = region_size - write_block_size;

        free_bytes -= write_block_size;

        STXXL_VERBOSE_WBTL("wbtl:nextwb  p" << FMT_A_S(region_pos, write_block_size) << " F    f" << FMT_A_C(free_bytes, free_space.size()));
        return region_pos;
    }

    STXXL_THROW2(io_error, "OutOfSpace, probably fragmented");

    return offset_type(-1);
}
Beispiel #8
0
int main(int argc, char** argv)
{
    _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
    IFile::OpenMode mode = IFile::O_ReadOnly;

    assert(argc>1);
    IFile *pFile = OpenDiskFile(argv[1], mode);
    BlockManager* pMgr = new BlockManager(pFile, mode==IFile::O_Truncate, offset_type(1024));

    BlockFS *pFS = new BlockFS(pMgr, mode);

    std::vector<std::string> names;
    pFS->ExportFileNames(names);
    for (std::vector<std::string>::iterator it = names.begin();
        it != names.end(); ++it)
    {
        IFile* pUnpackedFile = pFS->OpenFileInPackage(it->c_str());
        IFile* pTemp = OpenDiskFile(it->c_str(), IFile::O_Truncate);

        offset_type length = pUnpackedFile->GetSize();
        char* buff = new char[(size_t)length.offset];
        printf("Unpacking %s\n", it->c_str());

        pUnpackedFile->Read(buff, length);
        pTemp->Write(buff, length);

        delete []buff;
        delete pTemp;
        delete pUnpackedFile;
    }
    delete pFS;
    delete pMgr;
    delete pFile;
}
Beispiel #9
0
__STXXL_BEGIN_NAMESPACE


wbtl_file::wbtl_file(
    file * backend_file,
    size_type write_buffer_size,
    int write_buffers,
    int queue_id, int allocator_id) :
    disk_queued_file(queue_id, allocator_id), storage(backend_file), sz(0), write_block_size(write_buffer_size),
    free_bytes(0), curbuf(1), curpos(write_block_size)
{
    assert(write_buffers == 2); // currently hardcoded
    write_buffer[0] = static_cast<char *>(stxxl::aligned_alloc<BLOCK_ALIGN>(write_block_size));
    write_buffer[1] = static_cast<char *>(stxxl::aligned_alloc<BLOCK_ALIGN>(write_block_size));
    buffer_address[0] = offset_type(-1);
    buffer_address[1] = offset_type(-1);
}
Beispiel #10
0
void BlockManager::LoadExist(offset_type blocksize)
{
    m_pFile->Seek(offset_type(0), IFile::S_Begin);

    offset_type sizetoread;
    sizetoread.offset = sizeof(m_Header);
    m_pFile->Read(&m_Header, sizetoread);
    assert(m_Header.BlockSize == blocksize && "Block Size Error");
    CheckHeader();
}
Beispiel #11
0
void wbtl_file::swrite(void* buffer, offset_type offset, size_type bytes)
{
    scoped_mutex_lock buffer_lock(buffer_mutex);
    // is the block already mapped?
    {
        scoped_mutex_lock mapping_lock(mapping_mutex);
        sortseq::iterator physical = address_mapping.find(offset);
        STXXL_VERBOSE_WBTL("wbtl:swrite  l" << FMT_A_S(offset, bytes) << " @ <= p" <<
                           FMT_A_C(physical != address_mapping.end() ? physical->second : 0xffffffff, address_mapping.size()));
        if (physical != address_mapping.end()) {
            mapping_lock.unlock();
            // FIXME: special case if we can replace it in the current writing block
            discard(offset, bytes);
        }
    }

    if (bytes > write_block_size - curpos)
    {
        // not enough space in the current write buffer

        if (buffer_address[curbuf] != offset_type(-1)) {
            STXXL_VERBOSE_WBTL("wbtl:w2disk  p" << FMT_A_S(buffer_address[curbuf], write_block_size));

            // mark remaining part as free
            if (curpos < write_block_size)
                _add_free_region(buffer_address[curbuf] + curpos, write_block_size - curpos);

            if (backend_request.get()) {
                backend_request->wait(false);
            }

            backend_request = storage->awrite(write_buffer[curbuf], buffer_address[curbuf], write_block_size);
        }

        curbuf = 1 - curbuf;

        buffer_address[curbuf] = get_next_write_block();
        curpos = 0;
    }
    assert(bytes <= write_block_size - curpos);

    // write block into buffer
    memcpy(write_buffer[curbuf] + curpos, buffer, bytes);
    stats::get_instance()->write_cached(bytes);

    scoped_mutex_lock mapping_lock(mapping_mutex);
    address_mapping[offset] = buffer_address[curbuf] + curpos;
    reverse_mapping[buffer_address[curbuf] + curpos] = place(offset, bytes);
    STXXL_VERBOSE_WBTL("wbtl:swrite  l" << FMT_A_S(offset, bytes) << " @ => p" << FMT_A_C(buffer_address[curbuf] + curpos, address_mapping.size()));
    curpos += bytes;
}
Beispiel #12
0
int main(int argc, char* argv[])
{
    _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
    if(argc < 3)
    {
        printf("usage: %s directory package", argv[0]);
        return 0;
    }
    IFile::OpenMode mode = IFile::O_Write;
    if(!PathFileExistsA(argv[1]))
        mode = IFile::O_Truncate;
    IFile *pFile = OpenDiskFile(argv[1], mode);
    BlockManager* pMgr = new BlockManager(pFile, mode==IFile::O_Truncate, offset_type(1024));
    BlockFS *pFS = new BlockFS(pMgr, mode);
    std::vector<BlockFileEntry> vecEntries = pFS->GetEntries();
    std::map<std::string, MD5Index> mapEntries;
    for(std::vector<BlockFileEntry>::iterator it = vecEntries.begin();
        it != vecEntries.end(); ++it)
    {
        if(std::string("")!=it->name)
        {
            assert(mapEntries.find(it->name)==mapEntries.end());
            mapEntries[it->name] = it->index;
        }
    }
    std::vector<std::string> add;
    ScanFileRecursively(argv[2], pFS, mapEntries, add);

    for(std::map<std::string, MD5Index>::iterator it = mapEntries.begin(); it != mapEntries.end(); ++it)
        pFS->RemoveFile(it->first.c_str());

    for(std::vector<std::string>::iterator it = add.begin(); it != add.end(); ++it)
    {
        IFile* pTemp = OpenDiskFile(it->c_str(), IFile::O_ReadOnly);
        offset_type length = pTemp->GetSize();
        char* buff = new char[(size_t)length.offset];
        pTemp->Read(buff, length);
        printf("adding %s, %d bytes\n", it->c_str(), length);
        pFS->AddFile(it->c_str(), buff, length, length > pFS->GetBlockDataSize());
        delete[]buff;
        delete pTemp;
    }
    delete pFS;
    delete pMgr;
    delete pFile;
    return 0;
}
Beispiel #13
0
offset_type BlockManager::CalcOffset( offset_type blockid )
{
    return offset_type(sizeof(m_Header)+m_Header.BlockSize.offset*blockid.offset);
}