mirror of
https://github.com/GrammaticalFramework/gf-core.git
synced 2026-04-23 11:42:49 -06:00
make it possible to control the initial NGF size
This commit is contained in:
@@ -31,7 +31,7 @@ importGrammar readNGF pgf0 opts _
|
|||||||
putStr ("(Boot image "++fname++") ")
|
putStr ("(Boot image "++fname++") ")
|
||||||
return (Just fname)
|
return (Just fname)
|
||||||
else do return Nothing
|
else do return Nothing
|
||||||
pgf <- newNGF name mb_ngf_file
|
pgf <- newNGF name mb_ngf_file 0
|
||||||
return (Just pgf)
|
return (Just pgf)
|
||||||
importGrammar readNGF pgf0 _ [] = return pgf0
|
importGrammar readNGF pgf0 _ [] = return pgf0
|
||||||
importGrammar readNGF pgf0 opts fs
|
importGrammar readNGF pgf0 opts fs
|
||||||
|
|||||||
@@ -45,9 +45,9 @@ grammar2PGF opts mb_pgf gr am probs = do
|
|||||||
then removeFile fname
|
then removeFile fname
|
||||||
else return ()
|
else return ()
|
||||||
putStr ("(Boot image "++fname++") ")
|
putStr ("(Boot image "++fname++") ")
|
||||||
newNGF abs_name (Just fname)
|
newNGF abs_name (Just fname) 0
|
||||||
| otherwise ->
|
| otherwise ->
|
||||||
do newNGF abs_name Nothing
|
do newNGF abs_name Nothing 0
|
||||||
|
|
||||||
pgf <- modifyPGF pgf $ do
|
pgf <- modifyPGF pgf $ do
|
||||||
sequence_ [setAbstractFlag name value | (name,value) <- optionsPGF aflags]
|
sequence_ [setAbstractFlag name value | (name,value) <- optionsPGF aflags]
|
||||||
|
|||||||
@@ -134,9 +134,16 @@ struct PGF_INTERNAL_DECL malloc_state
|
|||||||
revision_entry revisions[];
|
revision_entry revisions[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static inline ssize_t get_mmap_size(size_t init_size, size_t page_size)
|
||||||
|
{
|
||||||
|
size_t mmap_size = ((init_size+page_size-1)/page_size)*page_size;
|
||||||
|
if (mmap_size < page_size*2)
|
||||||
|
mmap_size = page_size*2;
|
||||||
|
return mmap_size;
|
||||||
|
}
|
||||||
|
|
||||||
PGF_INTERNAL
|
PGF_INTERNAL
|
||||||
PgfDB::PgfDB(const char* filepath, int flags, int mode) {
|
PgfDB::PgfDB(const char* filepath, int flags, int mode, size_t init_size) {
|
||||||
bool is_new = false;
|
bool is_new = false;
|
||||||
|
|
||||||
fd = -1;
|
fd = -1;
|
||||||
@@ -147,7 +154,7 @@ PgfDB::PgfDB(const char* filepath, int flags, int mode) {
|
|||||||
|
|
||||||
if (filepath == NULL) {
|
if (filepath == NULL) {
|
||||||
this->filepath = NULL;
|
this->filepath = NULL;
|
||||||
mmap_size = page_size*2;
|
mmap_size = get_mmap_size(init_size, page_size);
|
||||||
is_new = true;
|
is_new = true;
|
||||||
} else {
|
} else {
|
||||||
fd = open(filepath, flags, mode);
|
fd = open(filepath, flags, mode);
|
||||||
@@ -163,7 +170,7 @@ PgfDB::PgfDB(const char* filepath, int flags, int mode) {
|
|||||||
|
|
||||||
is_new = false;
|
is_new = false;
|
||||||
if (mmap_size == 0) {
|
if (mmap_size == 0) {
|
||||||
mmap_size = page_size*2;
|
mmap_size = get_mmap_size(init_size, page_size);
|
||||||
if (ftruncate(fd, mmap_size) < 0) {
|
if (ftruncate(fd, mmap_size) < 0) {
|
||||||
int code = errno;
|
int code = errno;
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ public:
|
|||||||
// When the count is zero we release the database.
|
// When the count is zero we release the database.
|
||||||
size_t ref_count;
|
size_t ref_count;
|
||||||
|
|
||||||
PGF_INTERNAL_DECL PgfDB(const char* filepath, int flags, int mode);
|
PGF_INTERNAL_DECL PgfDB(const char* filepath, int flags, int mode, size_t init_size);
|
||||||
PGF_INTERNAL_DECL ~PgfDB();
|
PGF_INTERNAL_DECL ~PgfDB();
|
||||||
|
|
||||||
PGF_INTERNAL_DECL static txn_t get_txn_id();
|
PGF_INTERNAL_DECL static txn_t get_txn_id();
|
||||||
|
|||||||
@@ -46,12 +46,16 @@ PgfDB *pgf_read_pgf(const char* fpath, PgfRevision *revision,
|
|||||||
FILE *in = NULL;
|
FILE *in = NULL;
|
||||||
|
|
||||||
PGF_API_BEGIN {
|
PGF_API_BEGIN {
|
||||||
db = new PgfDB(NULL, 0, 0);
|
|
||||||
in = fopen(fpath, "rb");
|
in = fopen(fpath, "rb");
|
||||||
if (!in) {
|
if (!in) {
|
||||||
throw pgf_systemerror(errno, fpath);
|
throw pgf_systemerror(errno, fpath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fseek(in, 0, SEEK_END);
|
||||||
|
size_t pgf_size = ftell(in);
|
||||||
|
fseek(in, 0, SEEK_SET);
|
||||||
|
db = new PgfDB(NULL, 0, 0, pgf_size*7);
|
||||||
|
|
||||||
{
|
{
|
||||||
DB_scope scope(db, WRITER_SCOPE);
|
DB_scope scope(db, WRITER_SCOPE);
|
||||||
|
|
||||||
@@ -71,12 +75,12 @@ PgfDB *pgf_read_pgf(const char* fpath, PgfRevision *revision,
|
|||||||
return db;
|
return db;
|
||||||
} PGF_API_END
|
} PGF_API_END
|
||||||
|
|
||||||
if (in != NULL)
|
|
||||||
fclose(in);
|
|
||||||
|
|
||||||
if (db != NULL)
|
if (db != NULL)
|
||||||
delete db;
|
delete db;
|
||||||
|
|
||||||
|
if (in != NULL)
|
||||||
|
fclose(in);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,19 +94,23 @@ PgfDB *pgf_boot_ngf(const char* pgf_path, const char* ngf_path,
|
|||||||
FILE *in = NULL;
|
FILE *in = NULL;
|
||||||
|
|
||||||
PGF_API_BEGIN {
|
PGF_API_BEGIN {
|
||||||
db = new PgfDB(ngf_path, O_CREAT | O_EXCL | O_RDWR,
|
|
||||||
#ifndef _WIN32
|
|
||||||
S_IRUSR | S_IWUSR
|
|
||||||
#else
|
|
||||||
_S_IREAD | _S_IWRITE
|
|
||||||
#endif
|
|
||||||
);
|
|
||||||
|
|
||||||
in = fopen(pgf_path, "rb");
|
in = fopen(pgf_path, "rb");
|
||||||
if (!in) {
|
if (!in) {
|
||||||
throw pgf_systemerror(errno, pgf_path);
|
throw pgf_systemerror(errno, pgf_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fseek(in, 0, SEEK_END);
|
||||||
|
size_t pgf_size = ftell(in);
|
||||||
|
fseek(in, 0, SEEK_SET);
|
||||||
|
|
||||||
|
db = new PgfDB(ngf_path, O_CREAT | O_EXCL | O_RDWR,
|
||||||
|
#ifndef _WIN32
|
||||||
|
S_IRUSR | S_IWUSR,
|
||||||
|
#else
|
||||||
|
_S_IREAD | _S_IWRITE,
|
||||||
|
#endif
|
||||||
|
pgf_size*7);
|
||||||
|
|
||||||
{
|
{
|
||||||
DB_scope scope(db, WRITER_SCOPE);
|
DB_scope scope(db, WRITER_SCOPE);
|
||||||
|
|
||||||
@@ -141,7 +149,7 @@ PgfDB *pgf_read_ngf(const char *fpath,
|
|||||||
PgfDB *db = NULL;
|
PgfDB *db = NULL;
|
||||||
|
|
||||||
PGF_API_BEGIN {
|
PGF_API_BEGIN {
|
||||||
db = new PgfDB(fpath, O_RDWR, 0);
|
db = new PgfDB(fpath, O_RDWR, 0, 0);
|
||||||
|
|
||||||
{
|
{
|
||||||
DB_scope scope(db, WRITER_SCOPE);
|
DB_scope scope(db, WRITER_SCOPE);
|
||||||
@@ -165,6 +173,7 @@ PgfDB *pgf_read_ngf(const char *fpath,
|
|||||||
PGF_API
|
PGF_API
|
||||||
PgfDB *pgf_new_ngf(PgfText *abstract_name,
|
PgfDB *pgf_new_ngf(PgfText *abstract_name,
|
||||||
const char *fpath,
|
const char *fpath,
|
||||||
|
size_t init_size,
|
||||||
PgfRevision *revision,
|
PgfRevision *revision,
|
||||||
PgfExn* err)
|
PgfExn* err)
|
||||||
{
|
{
|
||||||
@@ -173,11 +182,11 @@ PgfDB *pgf_new_ngf(PgfText *abstract_name,
|
|||||||
PGF_API_BEGIN {
|
PGF_API_BEGIN {
|
||||||
db = new PgfDB(fpath, O_CREAT | O_EXCL | O_RDWR,
|
db = new PgfDB(fpath, O_CREAT | O_EXCL | O_RDWR,
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
S_IRUSR | S_IWUSR
|
S_IRUSR | S_IWUSR,
|
||||||
#else
|
#else
|
||||||
_S_IREAD | _S_IWRITE
|
_S_IREAD | _S_IWRITE,
|
||||||
#endif
|
#endif
|
||||||
);
|
init_size);
|
||||||
|
|
||||||
{
|
{
|
||||||
DB_scope scope(db, WRITER_SCOPE);
|
DB_scope scope(db, WRITER_SCOPE);
|
||||||
|
|||||||
@@ -276,6 +276,7 @@ PgfDB *pgf_read_ngf(const char* fpath,
|
|||||||
PGF_API_DECL
|
PGF_API_DECL
|
||||||
PgfDB *pgf_new_ngf(PgfText *abstract_name,
|
PgfDB *pgf_new_ngf(PgfText *abstract_name,
|
||||||
const char *fpath,
|
const char *fpath,
|
||||||
|
size_t init_size,
|
||||||
PgfRevision *revision,
|
PgfRevision *revision,
|
||||||
PgfExn* err);
|
PgfExn* err);
|
||||||
|
|
||||||
|
|||||||
@@ -177,13 +177,13 @@ readNGF fpath =
|
|||||||
-- Aside from the name, the grammar is otherwise empty but can be later
|
-- Aside from the name, the grammar is otherwise empty but can be later
|
||||||
-- populated with new functions and categories. If fpath is Nothing then
|
-- populated with new functions and categories. If fpath is Nothing then
|
||||||
-- the file is not stored on the disk but only in memory.
|
-- the file is not stored on the disk but only in memory.
|
||||||
newNGF :: AbsName -> Maybe FilePath -> IO PGF
|
newNGF :: AbsName -> Maybe FilePath -> Int -> IO PGF
|
||||||
newNGF abs_name mb_fpath =
|
newNGF abs_name mb_fpath init_size =
|
||||||
withText abs_name $ \c_abs_name ->
|
withText abs_name $ \c_abs_name ->
|
||||||
maybe (\f -> f nullPtr) withCString mb_fpath $ \c_fpath ->
|
maybe (\f -> f nullPtr) withCString mb_fpath $ \c_fpath ->
|
||||||
alloca $ \p_revision ->
|
alloca $ \p_revision ->
|
||||||
mask_ $ do
|
mask_ $ do
|
||||||
c_db <- withPgfExn "newNGF" (pgf_new_ngf c_abs_name c_fpath p_revision)
|
c_db <- withPgfExn "newNGF" (pgf_new_ngf c_abs_name c_fpath (fromIntegral init_size) p_revision)
|
||||||
c_revision <- peek p_revision
|
c_revision <- peek p_revision
|
||||||
fptr <- newForeignPtrEnv pgf_free_revision c_db c_revision
|
fptr <- newForeignPtrEnv pgf_free_revision c_db c_revision
|
||||||
return (PGF c_db fptr Map.empty)
|
return (PGF c_db fptr Map.empty)
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ foreign import ccall "wrapper" wrapProbsCallback :: Wrapper ProbsCallback
|
|||||||
foreign import ccall "pgf_read_ngf"
|
foreign import ccall "pgf_read_ngf"
|
||||||
pgf_read_ngf :: CString -> Ptr (Ptr PGF) -> Ptr PgfExn -> IO (Ptr PgfDB)
|
pgf_read_ngf :: CString -> Ptr (Ptr PGF) -> Ptr PgfExn -> IO (Ptr PgfDB)
|
||||||
|
|
||||||
foreign import ccall pgf_new_ngf :: Ptr PgfText -> CString -> Ptr (Ptr PGF) -> Ptr PgfExn -> IO (Ptr PgfDB)
|
foreign import ccall pgf_new_ngf :: Ptr PgfText -> CString -> CSize -> Ptr (Ptr PGF) -> Ptr PgfExn -> IO (Ptr PgfDB)
|
||||||
|
|
||||||
foreign import ccall pgf_merge_pgf :: Ptr PgfDB -> Ptr PGF -> CString -> Ptr PgfExn -> IO ()
|
foreign import ccall pgf_merge_pgf :: Ptr PgfDB -> Ptr PGF -> CString -> Ptr PgfExn -> IO ()
|
||||||
|
|
||||||
|
|||||||
@@ -523,7 +523,7 @@ PGF_writePGF(PGFObject *self, PyObject *args, PyObject *kwargs)
|
|||||||
|
|
||||||
const char *fpath;
|
const char *fpath;
|
||||||
PyObject *py_langs = NULL;
|
PyObject *py_langs = NULL;
|
||||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|O!", &kwds[0], &fpath, &PyList_Type, &py_langs))
|
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|O!", kwds, &fpath, &PyList_Type, &py_langs))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
PgfText **langs = NULL;
|
PgfText **langs = NULL;
|
||||||
@@ -1327,20 +1327,22 @@ pgf_readNGF(PyObject *self, PyObject *args)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static PGFObject *
|
static PGFObject *
|
||||||
pgf_newNGF(PyObject *self, PyObject *args)
|
pgf_newNGF(PyObject *self, PyObject *args, PyObject *kwargs)
|
||||||
{
|
{
|
||||||
|
char *kwds[] = {"","file","size",NULL};
|
||||||
|
|
||||||
const char *s;
|
const char *s;
|
||||||
Py_ssize_t size;
|
Py_ssize_t size;
|
||||||
const char *fpath = NULL;
|
const char *fpath = NULL;
|
||||||
if (!PyArg_ParseTuple(args, "s#|s", &s, &size, &fpath))
|
Py_ssize_t init_size = 0;
|
||||||
|
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#|sn", kwds, &s, &size, &fpath, &init_size))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
PgfText *absname = CString_AsPgfText(s, size);
|
PgfText *absname = CString_AsPgfText(s, size);
|
||||||
|
|
||||||
PGFObject *py_pgf = (PGFObject *)pgf_PGFType.tp_alloc(&pgf_PGFType, 0);
|
PGFObject *py_pgf = (PGFObject *)pgf_PGFType.tp_alloc(&pgf_PGFType, 0);
|
||||||
|
|
||||||
PgfExn err;
|
PgfExn err;
|
||||||
py_pgf->db = pgf_new_ngf(absname, fpath, &py_pgf->revision, &err);
|
py_pgf->db = pgf_new_ngf(absname, fpath, init_size, &py_pgf->revision, &err);
|
||||||
FreePgfText(absname);
|
FreePgfText(absname);
|
||||||
if (handleError(err) != PGF_EXN_NONE) {
|
if (handleError(err) != PGF_EXN_NONE) {
|
||||||
Py_DECREF(py_pgf);
|
Py_DECREF(py_pgf);
|
||||||
@@ -1508,7 +1510,7 @@ static PyMethodDef module_methods[] = {
|
|||||||
"Reads a PGF file into memory and stores the unpacked data in an NGF file"},
|
"Reads a PGF file into memory and stores the unpacked data in an NGF file"},
|
||||||
{"readNGF", (void*)pgf_readNGF, METH_VARARGS,
|
{"readNGF", (void*)pgf_readNGF, METH_VARARGS,
|
||||||
"Reads an NGF file into memory"},
|
"Reads an NGF file into memory"},
|
||||||
{"newNGF", (void*)pgf_newNGF, METH_VARARGS,
|
{"newNGF", (void*)pgf_newNGF, METH_VARARGS | METH_KEYWORDS,
|
||||||
"Creates a new NGF file with the given name"},
|
"Creates a new NGF file with the given name"},
|
||||||
|
|
||||||
{"readExpr", (void*)pgf_readExpr, METH_VARARGS,
|
{"readExpr", (void*)pgf_readExpr, METH_VARARGS,
|
||||||
|
|||||||
Reference in New Issue
Block a user