File: fileperblock_file.cpp

package info (click to toggle)
libstxxl 1.4.1-6
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 5,476 kB
  • sloc: cpp: 45,101; ansic: 4,071; perl: 610; sh: 555; xml: 174; makefile: 18
file content (166 lines) | stat: -rw-r--r-- 5,482 bytes parent folder | download | duplicates (4)
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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
/***************************************************************************
 *  lib/io/fileperblock_file.cpp
 *
 *  Part of the STXXL. See http://stxxl.sourceforge.net
 *
 *  Copyright (C) 2008, 2009 Johannes Singler <singler@ira.uka.de>
 *  Copyright (C) 2008 Andreas Beckmann <beckmann@cs.uni-frankfurt.de>
 *
 *  Distributed under the Boost Software License, Version 1.0.
 *  (See accompanying file LICENSE_1_0.txt or copy at
 *  http://www.boost.org/LICENSE_1_0.txt)
 **************************************************************************/

#include <cassert>
#include <cstdio>
#include <iomanip>
#include <sstream>
#include <string>

#include <stxxl/bits/common/aligned_alloc.h>
#include <stxxl/bits/common/counting_ptr.h>
#include <stxxl/bits/common/error_handling.h>
#include <stxxl/bits/common/exceptions.h>
#include <stxxl/bits/config.h>
#include <stxxl/bits/io/boostfd_file.h>
#include <stxxl/bits/io/completion_handler.h>
#include <stxxl/bits/io/disk_queued_file.h>
#include <stxxl/bits/io/file.h>
#include <stxxl/bits/io/fileperblock_file.h>
#include <stxxl/bits/io/mmap_file.h>
#include <stxxl/bits/io/boostfd_file.h>
#include <stxxl/bits/io/wincall_file.h>
#include <stxxl/bits/io/request.h>
#include <stxxl/bits/io/serving_request.h>
#include <stxxl/bits/io/syscall_file.h>
#include <stxxl/bits/io/wincall_file.h>
#include <stxxl/bits/namespace.h>
#include <stxxl/bits/unused.h>
#include <stxxl/bits/verbose.h>
#include "ufs_platform.h"

STXXL_BEGIN_NAMESPACE

template <class base_file_type>
fileperblock_file<base_file_type>::fileperblock_file(
    const std::string& filename_prefix,
    int mode,
    int queue_id,
    int allocator_id,
    unsigned int device_id)
    : file(device_id),
      disk_queued_file(queue_id, allocator_id),
      filename_prefix(filename_prefix),
      mode(mode),
      current_size(0),
      lock_file_created(false),
      lock_file(filename_prefix + "_fpb_lock", mode, queue_id)
{ }

template <class base_file_type>
fileperblock_file<base_file_type>::~fileperblock_file()
{
    if (lock_file_created)
    {
        if (::remove((filename_prefix + "_fpb_lock").c_str()) != 0)
            STXXL_ERRMSG("remove() error on path=" << filename_prefix << "_fpb_lock error=" << strerror(errno));
    }
}

template <class base_file_type>
std::string fileperblock_file<base_file_type>::filename_for_block(offset_type offset)
{
    std::ostringstream name;
    //enough for 1 billion blocks
    name << filename_prefix << "_fpb_" << std::setw(20) << std::setfill('0') << offset;
    return name.str();
}

template <class base_file_type>
void fileperblock_file<base_file_type>::serve(void* buffer, offset_type offset,
                                              size_type bytes, request::request_type type)
{
    base_file_type base_file(filename_for_block(offset), mode, get_queue_id());
    base_file.set_size(bytes);
    base_file.serve(buffer, 0, bytes, type);
}

template <class base_file_type>
void fileperblock_file<base_file_type>::lock()
{
    if (!lock_file_created)
    {
        //create lock file and fill it with one page, an empty file cannot be locked
        const int page_size = STXXL_BLOCK_ALIGN;
        void* one_page = aligned_alloc<STXXL_BLOCK_ALIGN>(page_size);
#if STXXL_WITH_VALGRIND
        memset(one_page, 0, page_size);
#endif
        lock_file.set_size(page_size);
        request_ptr r = lock_file.awrite(one_page, 0, page_size);
        r->wait();
        aligned_dealloc<STXXL_BLOCK_ALIGN>(one_page);
        lock_file_created = true;
    }
    lock_file.lock();
}

template <class base_file_type>
void fileperblock_file<base_file_type>::discard(offset_type offset, offset_type length)
{
    STXXL_UNUSED(length);
#ifdef STXXL_FILEPERBLOCK_NO_DELETE
    if (::truncate(filename_for_block(offset).c_str(), 0) != 0)
        STXXL_ERRMSG("truncate() error on path=" << filename_for_block(offset) << " error=" << strerror(errno));
#else
    if (::remove(filename_for_block(offset).c_str()) != 0)
        STXXL_ERRMSG("remove() error on path=" << filename_for_block(offset) << " error=" << strerror(errno));
#endif

    STXXL_VERBOSE2("discard " << offset << " + " << length);
}

template <class base_file_type>
void fileperblock_file<base_file_type>::export_files(offset_type offset, offset_type length, std::string filename)
{
    std::string original(filename_for_block(offset));
    filename.insert(0, original.substr(0, original.find_last_of("/") + 1));
    if (::remove(filename.c_str()) != 0)
        STXXL_ERRMSG("remove() error on path=" << filename << " error=" << strerror(errno));

    if (::rename(original.c_str(), filename.c_str()) != 0)
        STXXL_ERRMSG("rename() error on path=" << filename << " to=" << original << " error=" << strerror(errno));

#if !STXXL_WINDOWS
    //TODO: implement on Windows
    if (::truncate(filename.c_str(), length) != 0) {
        STXXL_THROW_ERRNO(io_error, "Error doing truncate()");
    }
#else
    STXXL_UNUSED(length);
#endif
}

template <class base_file_type>
const char* fileperblock_file<base_file_type>::io_type() const
{
    return "fileperblock";
}

////////////////////////////////////////////////////////////////////////////

template class fileperblock_file<syscall_file>;

#if STXXL_HAVE_MMAP_FILE
template class fileperblock_file<mmap_file>;
#endif

#if STXXL_HAVE_WINCALL_FILE
template class fileperblock_file<wincall_file>;
#endif

#if STXXL_HAVE_BOOSTFD_FILE
template class fileperblock_file<boostfd_file>;
#endif

STXXL_END_NAMESPACE