forked from GitHub/gf-core
first draft of the new allocator with transactions support
This commit is contained in:
@@ -136,4 +136,4 @@ importSource opts files = lift0 $ GF.importSource opts files
|
|||||||
link opts pgf src = lift0 $ GF.link opts pgf src
|
link opts pgf src = lift0 $ GF.link opts pgf src
|
||||||
|
|
||||||
modifyPGF gr t = lift0 (PGFT.modifyPGF gr t)
|
modifyPGF gr t = lift0 (PGFT.modifyPGF gr t)
|
||||||
checkoutPGF gr b = lift0 (PGFT.checkoutPGF gr b)
|
checkoutPGF gr = lift0 (PGFT.checkoutPGF gr)
|
||||||
|
|||||||
@@ -154,8 +154,8 @@ execute1' s0 =
|
|||||||
checkout = do
|
checkout = do
|
||||||
mb_pgf <- gets multigrammar
|
mb_pgf <- gets multigrammar
|
||||||
case mb_pgf of
|
case mb_pgf of
|
||||||
Just pgf -> do mb_pgf <- lift $ checkoutPGF pgf "master"
|
Just pgf -> do pgf <- lift $ checkoutPGF pgf
|
||||||
modify $ \gfenv -> gfenv{pgfenv = (fst (pgfenv gfenv),mb_pgf)}
|
modify $ \gfenv -> gfenv{pgfenv = (fst (pgfenv gfenv),Just pgf)}
|
||||||
Nothing -> return ()
|
Nothing -> return ()
|
||||||
|
|
||||||
interruptible :: ShellM Bool -> ShellM Bool
|
interruptible :: ShellM Bool -> ShellM Bool
|
||||||
|
|||||||
@@ -2,31 +2,31 @@
|
|||||||
|
|
||||||
void PgfFlag::release(ref<PgfFlag> flag)
|
void PgfFlag::release(ref<PgfFlag> flag)
|
||||||
{
|
{
|
||||||
pgf_literal_free(flag->value);
|
pgf_literal_release(flag->value);
|
||||||
PgfDB::free(flag);
|
PgfDB::free(flag, flag->name.size+1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PgfAbsFun::release(ref<PgfAbsFun> absfun)
|
void PgfAbsFun::release(ref<PgfAbsFun> absfun)
|
||||||
{
|
{
|
||||||
pgf_type_free(absfun->type);
|
pgf_type_release(absfun->type);
|
||||||
|
|
||||||
if (absfun->bytecode != 0) {
|
if (absfun->bytecode != 0) {
|
||||||
PgfDB::free(absfun->bytecode);
|
PgfDB::free(absfun->bytecode);
|
||||||
}
|
}
|
||||||
|
|
||||||
PgfDB::free(absfun);
|
PgfDB::free(absfun, absfun->name.size+1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PgfAbsCat::release(ref<PgfAbsCat> abscat)
|
void PgfAbsCat::release(ref<PgfAbsCat> abscat)
|
||||||
{
|
{
|
||||||
pgf_context_free(abscat->context);
|
pgf_context_release(abscat->context);
|
||||||
PgfDB::free(abscat);
|
PgfDB::free(abscat, abscat->name.size+1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PgfPGF::release(ref<PgfPGF> pgf)
|
void PgfPGF::release(ref<PgfPGF> pgf)
|
||||||
{
|
{
|
||||||
namespace_release(pgf->gflags);
|
namespace_release(pgf->gflags);
|
||||||
PgfDB::free(pgf->abstract.name);
|
text_db_release(pgf->abstract.name);
|
||||||
namespace_release(pgf->abstract.aflags);
|
namespace_release(pgf->abstract.aflags);
|
||||||
namespace_release(pgf->abstract.funs);
|
namespace_release(pgf->abstract.funs);
|
||||||
namespace_release(pgf->abstract.cats);
|
namespace_release(pgf->abstract.cats);
|
||||||
@@ -41,112 +41,112 @@ void PgfConcr::release(ref<PgfConcr> concr)
|
|||||||
namespace_release(concr->lincats);
|
namespace_release(concr->lincats);
|
||||||
phrasetable_release(concr->phrasetable);
|
phrasetable_release(concr->phrasetable);
|
||||||
namespace_release(concr->printnames);
|
namespace_release(concr->printnames);
|
||||||
PgfDB::free(concr);
|
PgfDB::free(concr, concr->name.size+1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PgfConcrLincat::release(ref<PgfConcrLincat> lincat)
|
void PgfConcrLincat::release(ref<PgfConcrLincat> lincat)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < lincat->fields->len; i++) {
|
for (size_t i = 0; i < lincat->fields->len; i++) {
|
||||||
PgfDB::free(*vector_elem(lincat->fields, i));
|
text_db_release(*vector_elem(lincat->fields, i));
|
||||||
}
|
}
|
||||||
|
Vector<ref<PgfText>>::release(lincat->fields);
|
||||||
|
|
||||||
PgfDB::free(lincat->fields);
|
|
||||||
|
|
||||||
for (size_t i = 0; i < lincat->args->len; i++) {
|
for (size_t i = 0; i < lincat->args->len; i++) {
|
||||||
PgfDB::free(vector_elem(lincat->args, i)->param);
|
PgfLParam::release(vector_elem(lincat->args, i)->param);
|
||||||
}
|
}
|
||||||
PgfDB::free(lincat->args);
|
Vector<PgfPArg>::release(lincat->args);
|
||||||
|
|
||||||
for (size_t i = 0; i < lincat->res->len; i++) {
|
for (size_t i = 0; i < lincat->res->len; i++) {
|
||||||
ref<PgfPResult> res = *vector_elem(lincat->res, i);
|
PgfPResult::release(*vector_elem(lincat->res, i));
|
||||||
if (res->vars != 0)
|
|
||||||
PgfDB::free(res->vars);
|
|
||||||
PgfDB::free(res);
|
|
||||||
}
|
}
|
||||||
PgfDB::free(lincat->res);
|
Vector<ref<PgfPResult>>::release(lincat->res);
|
||||||
|
|
||||||
for (size_t i = 0; i < lincat->seqs->len; i++) {
|
Vector<ref<PgfSequence>>::release(lincat->seqs);
|
||||||
ref<PgfSequence> seq = *vector_elem(lincat->seqs, i);
|
|
||||||
if (!(--seq->ref_count)) {
|
|
||||||
PgfSequence::release(seq);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
PgfDB::free(lincat->seqs);
|
|
||||||
|
|
||||||
PgfDB::free(lincat);
|
PgfDB::free(lincat, lincat->name.size+1);
|
||||||
}
|
}
|
||||||
|
|
||||||
PGF_INTERNAL
|
void PgfLParam::release(ref<PgfLParam> param)
|
||||||
void pgf_symbol_free(PgfSymbol sym)
|
|
||||||
{
|
{
|
||||||
switch (ref<PgfSymbol>::get_tag(sym)) {
|
PgfDB::free(param, param->n_terms*sizeof(param->terms[0]));
|
||||||
case PgfSymbolKP::tag: {
|
}
|
||||||
auto sym_kp = ref<PgfSymbolKP>::untagged(sym);
|
|
||||||
PgfSequence::release(sym_kp->default_form);
|
void PgfPResult::release(ref<PgfPResult> res)
|
||||||
for (size_t i = 0; i < sym_kp->alts.len; i++) {
|
{
|
||||||
PgfSequence::release(sym_kp->alts.data[i].form);
|
if (res->vars != 0)
|
||||||
for (size_t j = 0; j < sym_kp->alts.data[i].prefixes->len; j++) {
|
Vector<PgfVariableRange>::release(res->vars);
|
||||||
ref<PgfText> prefix = *vector_elem(sym_kp->alts.data[i].prefixes, j);
|
PgfDB::free(res, res->param.n_terms*sizeof(res->param.terms[0]));
|
||||||
PgfDB::free(prefix);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
PgfDB::free(sym_kp);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PgfSymbolBIND::tag:
|
|
||||||
case PgfSymbolSOFTBIND::tag:
|
|
||||||
case PgfSymbolNE::tag:
|
|
||||||
case PgfSymbolSOFTSPACE::tag:
|
|
||||||
case PgfSymbolCAPIT::tag:
|
|
||||||
case PgfSymbolALLCAPIT::tag:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
PgfDB::free(ref<void>::untagged(sym));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PgfSequence::release(ref<PgfSequence> seq)
|
void PgfSequence::release(ref<PgfSequence> seq)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < seq->syms.len; i++) {
|
for (size_t i = 0; i < seq->syms.len; i++) {
|
||||||
PgfSymbol sym = *vector_elem(&seq->syms, i);
|
PgfSymbol sym = *vector_elem(&seq->syms, i);
|
||||||
pgf_symbol_free(sym);
|
|
||||||
}
|
|
||||||
PgfDB::free(seq);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PgfSequenceBackrefs::release(ref<PgfSequenceBackrefs> backrefs)
|
switch (ref<PgfSymbol>::get_tag(sym)) {
|
||||||
{
|
case PgfSymbolCat::tag: {
|
||||||
PgfDB::free(backrefs);
|
auto sym_cat = ref<PgfSymbolCat>::untagged(sym);
|
||||||
|
PgfDB::free(sym_cat, sym_cat->r.n_terms*sizeof(sym_cat->r.terms[0]));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PgfSymbolLit::tag: {
|
||||||
|
auto sym_lit = ref<PgfSymbolLit>::untagged(sym);
|
||||||
|
PgfDB::free(sym_lit, sym_lit->r.n_terms*sizeof(sym_lit->r.terms[0]));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PgfSymbolVar::tag:
|
||||||
|
PgfDB::free(ref<PgfSymbolVar>::untagged(sym));
|
||||||
|
break;
|
||||||
|
case PgfSymbolKS::tag: {
|
||||||
|
auto sym_ks = ref<PgfSymbolKS>::untagged(sym);
|
||||||
|
PgfDB::free(sym_ks, sym_ks->token.size+1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PgfSymbolKP::tag: {
|
||||||
|
auto sym_kp = ref<PgfSymbolKP>::untagged(sym);
|
||||||
|
PgfSequence::release(sym_kp->default_form);
|
||||||
|
for (size_t i = 0; i < sym_kp->alts.len; i++) {
|
||||||
|
PgfSequence::release(sym_kp->alts.data[i].form);
|
||||||
|
for (size_t j = 0; j < sym_kp->alts.data[i].prefixes->len; j++) {
|
||||||
|
text_db_release(*vector_elem(sym_kp->alts.data[i].prefixes, j));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PgfDB::free(sym_kp, sym_kp->alts.len*sizeof(PgfAlternative));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PgfSymbolBIND::tag:
|
||||||
|
case PgfSymbolSOFTBIND::tag:
|
||||||
|
case PgfSymbolNE::tag:
|
||||||
|
case PgfSymbolSOFTSPACE::tag:
|
||||||
|
case PgfSymbolCAPIT::tag:
|
||||||
|
case PgfSymbolALLCAPIT::tag:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw pgf_error("Unknown symbol tag");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PgfDB::free(seq,seq->syms.len*sizeof(PgfSymbol));
|
||||||
}
|
}
|
||||||
|
|
||||||
void PgfConcrLin::release(ref<PgfConcrLin> lin)
|
void PgfConcrLin::release(ref<PgfConcrLin> lin)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < lin->args->len; i++) {
|
for (size_t i = 0; i < lin->args->len; i++) {
|
||||||
PgfDB::free(vector_elem(lin->args, i)->param);
|
PgfLParam::release(vector_elem(lin->args, i)->param);
|
||||||
}
|
}
|
||||||
PgfDB::free(lin->args);
|
Vector<PgfPArg>::release(lin->args);
|
||||||
|
|
||||||
for (size_t i = 0; i < lin->res->len; i++) {
|
for (size_t i = 0; i < lin->res->len; i++) {
|
||||||
ref<PgfPResult> res = *vector_elem(lin->res, i);
|
PgfPResult::release(*vector_elem(lin->res, i));
|
||||||
if (res->vars != 0)
|
|
||||||
PgfDB::free(res->vars);
|
|
||||||
PgfDB::free(res);
|
|
||||||
}
|
}
|
||||||
PgfDB::free(lin->res);
|
Vector<ref<PgfPResult>>::release(lin->res);
|
||||||
|
|
||||||
for (size_t i = 0; i < lin->seqs->len; i++) {
|
Vector<ref<PgfSequence>>::release(lin->seqs);
|
||||||
ref<PgfSequence> seq = *vector_elem(lin->seqs, i);
|
|
||||||
if (!(--seq->ref_count)) {
|
|
||||||
PgfSequence::release(seq);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
PgfDB::free(lin->seqs);
|
|
||||||
|
|
||||||
PgfDB::free(lin);
|
PgfDB::free(lin, lin->name.size+1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PgfConcrPrintname::release(ref<PgfConcrPrintname> printname)
|
void PgfConcrPrintname::release(ref<PgfConcrPrintname> printname)
|
||||||
{
|
{
|
||||||
PgfDB::free(printname->printname);
|
text_db_release(printname->printname);
|
||||||
PgfDB::free(printname);
|
PgfDB::free(printname, printname->name.size+1);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,7 +73,6 @@ class PgfConcr;
|
|||||||
#include "expr.h"
|
#include "expr.h"
|
||||||
|
|
||||||
struct PGF_INTERNAL_DECL PgfFlag {
|
struct PGF_INTERNAL_DECL PgfFlag {
|
||||||
size_t ref_count;
|
|
||||||
PgfLiteral value;
|
PgfLiteral value;
|
||||||
PgfText name;
|
PgfText name;
|
||||||
|
|
||||||
@@ -81,8 +80,6 @@ struct PGF_INTERNAL_DECL PgfFlag {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct PGF_INTERNAL_DECL PgfAbsFun {
|
struct PGF_INTERNAL_DECL PgfAbsFun {
|
||||||
size_t ref_count;
|
|
||||||
|
|
||||||
ref<PgfDTyp> type;
|
ref<PgfDTyp> type;
|
||||||
int arity;
|
int arity;
|
||||||
ref<char> bytecode;
|
ref<char> bytecode;
|
||||||
@@ -93,8 +90,6 @@ struct PGF_INTERNAL_DECL PgfAbsFun {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct PGF_INTERNAL_DECL PgfAbsCat {
|
struct PGF_INTERNAL_DECL PgfAbsCat {
|
||||||
size_t ref_count;
|
|
||||||
|
|
||||||
ref<Vector<PgfHypo>> context;
|
ref<Vector<PgfHypo>> context;
|
||||||
prob_t prob;
|
prob_t prob;
|
||||||
PgfText name;
|
PgfText name;
|
||||||
@@ -116,6 +111,8 @@ struct PGF_INTERNAL_DECL PgfLParam {
|
|||||||
size_t factor;
|
size_t factor;
|
||||||
size_t var;
|
size_t var;
|
||||||
} terms[];
|
} terms[];
|
||||||
|
|
||||||
|
static void release(ref<PgfLParam> param);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PGF_INTERNAL_DECL PgfVariableRange {
|
struct PGF_INTERNAL_DECL PgfVariableRange {
|
||||||
@@ -130,15 +127,16 @@ struct PGF_INTERNAL_DECL PgfPArg {
|
|||||||
struct PGF_INTERNAL_DECL PgfPResult {
|
struct PGF_INTERNAL_DECL PgfPResult {
|
||||||
ref<Vector<PgfVariableRange>> vars;
|
ref<Vector<PgfVariableRange>> vars;
|
||||||
PgfLParam param;
|
PgfLParam param;
|
||||||
|
|
||||||
|
static void release(ref<PgfPResult> res);
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef object PgfSymbol;
|
typedef object PgfSymbol;
|
||||||
|
|
||||||
struct PGF_INTERNAL_DECL PgfSequence {
|
struct PGF_INTERNAL_DECL PgfSequence {
|
||||||
size_t ref_count;
|
|
||||||
Vector<PgfSymbol> syms;
|
Vector<PgfSymbol> syms;
|
||||||
|
|
||||||
static void release(ref<PgfSequence> lincat);
|
static void release(ref<PgfSequence> seq);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PGF_INTERNAL_DECL PgfSequenceBackref {
|
struct PGF_INTERNAL_DECL PgfSequenceBackref {
|
||||||
@@ -146,14 +144,6 @@ struct PGF_INTERNAL_DECL PgfSequenceBackref {
|
|||||||
size_t seq_index;
|
size_t seq_index;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PGF_INTERNAL_DECL PgfSequenceBackrefs {
|
|
||||||
size_t ref_count;
|
|
||||||
Vector<PgfSequenceBackref> list;
|
|
||||||
|
|
||||||
static
|
|
||||||
void release(ref<PgfSequenceBackrefs> backrefs);
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PGF_INTERNAL_DECL PgfSymbolCat {
|
struct PGF_INTERNAL_DECL PgfSymbolCat {
|
||||||
static const uint8_t tag = 0;
|
static const uint8_t tag = 0;
|
||||||
size_t d;
|
size_t d;
|
||||||
@@ -215,14 +205,9 @@ struct PGF_INTERNAL_DECL PgfSymbolALLCAPIT {
|
|||||||
static const uint8_t tag = 10;
|
static const uint8_t tag = 10;
|
||||||
};
|
};
|
||||||
|
|
||||||
PGF_INTERNAL_DECL
|
|
||||||
void pgf_symbol_free(PgfSymbol sym);
|
|
||||||
|
|
||||||
struct PGF_INTERNAL_DECL PgfConcrLincat {
|
struct PGF_INTERNAL_DECL PgfConcrLincat {
|
||||||
static const uint8_t tag = 0;
|
static const uint8_t tag = 0;
|
||||||
|
|
||||||
size_t ref_count;
|
|
||||||
|
|
||||||
ref<PgfAbsCat> abscat;
|
ref<PgfAbsCat> abscat;
|
||||||
|
|
||||||
ref<Vector<ref<PgfText>>> fields;
|
ref<Vector<ref<PgfText>>> fields;
|
||||||
@@ -240,8 +225,6 @@ struct PGF_INTERNAL_DECL PgfConcrLincat {
|
|||||||
struct PGF_INTERNAL_DECL PgfConcrLin {
|
struct PGF_INTERNAL_DECL PgfConcrLin {
|
||||||
static const uint8_t tag = 1;
|
static const uint8_t tag = 1;
|
||||||
|
|
||||||
size_t ref_count;
|
|
||||||
|
|
||||||
ref<PgfAbsFun> absfun;
|
ref<PgfAbsFun> absfun;
|
||||||
|
|
||||||
ref<Vector<PgfPArg>> args;
|
ref<Vector<PgfPArg>> args;
|
||||||
@@ -254,7 +237,6 @@ struct PGF_INTERNAL_DECL PgfConcrLin {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct PGF_INTERNAL_DECL PgfConcrPrintname {
|
struct PGF_INTERNAL_DECL PgfConcrPrintname {
|
||||||
size_t ref_count;
|
|
||||||
ref<PgfText> printname;
|
ref<PgfText> printname;
|
||||||
PgfText name;
|
PgfText name;
|
||||||
|
|
||||||
@@ -262,8 +244,8 @@ struct PGF_INTERNAL_DECL PgfConcrPrintname {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct PGF_INTERNAL_DECL PgfConcr {
|
struct PGF_INTERNAL_DECL PgfConcr {
|
||||||
size_t ref_count;
|
static const uint8_t tag = 1;
|
||||||
size_t ref_count_ex;
|
|
||||||
Namespace<PgfFlag> cflags;
|
Namespace<PgfFlag> cflags;
|
||||||
Namespace<PgfConcrLin> lins;
|
Namespace<PgfConcrLin> lins;
|
||||||
Namespace<PgfConcrLincat> lincats;
|
Namespace<PgfConcrLincat> lincats;
|
||||||
@@ -282,7 +264,7 @@ struct PGF_INTERNAL_DECL PgfConcr {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct PGF_INTERNAL_DECL PgfPGF {
|
struct PGF_INTERNAL_DECL PgfPGF {
|
||||||
size_t ref_count;
|
static const uint8_t tag = 0;
|
||||||
|
|
||||||
uint16_t major_version;
|
uint16_t major_version;
|
||||||
uint16_t minor_version;
|
uint16_t minor_version;
|
||||||
@@ -290,18 +272,7 @@ struct PGF_INTERNAL_DECL PgfPGF {
|
|||||||
PgfAbstr abstract;
|
PgfAbstr abstract;
|
||||||
Namespace<PgfConcr> concretes;
|
Namespace<PgfConcr> concretes;
|
||||||
|
|
||||||
// If the revision is transient, then it is in a double-linked list
|
|
||||||
// with all other transient revisions.
|
|
||||||
ref<PgfPGF> prev, next;
|
|
||||||
|
|
||||||
// The name lets the user to find a particular revision in
|
|
||||||
// the database.
|
|
||||||
PgfText name;
|
|
||||||
|
|
||||||
static void release(ref<PgfPGF> pgf);
|
static void release(ref<PgfPGF> pgf);
|
||||||
};
|
};
|
||||||
|
|
||||||
extern PGF_INTERNAL_DECL size_t master_size;
|
|
||||||
extern PGF_INTERNAL_DECL char master_text[];
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -8,6 +8,7 @@ class PgfDB;
|
|||||||
extern PGF_INTERNAL_DECL __thread unsigned char* current_base __attribute__((tls_model("initial-exec")));
|
extern PGF_INTERNAL_DECL __thread unsigned char* current_base __attribute__((tls_model("initial-exec")));
|
||||||
extern PGF_INTERNAL_DECL __thread PgfDB* current_db __attribute__((tls_model("initial-exec")));
|
extern PGF_INTERNAL_DECL __thread PgfDB* current_db __attribute__((tls_model("initial-exec")));
|
||||||
|
|
||||||
|
struct block_descr;
|
||||||
struct malloc_state;
|
struct malloc_state;
|
||||||
|
|
||||||
template<class A> class PGF_INTERNAL_DECL ref {
|
template<class A> class PGF_INTERNAL_DECL ref {
|
||||||
@@ -37,10 +38,9 @@ public:
|
|||||||
|
|
||||||
object as_object() const { return offset; }
|
object as_object() const { return offset; }
|
||||||
|
|
||||||
static
|
object tagged() {
|
||||||
object tagged(ref<A> ref) {
|
|
||||||
assert(A::tag < MALLOC_ALIGN_MASK + 1);
|
assert(A::tag < MALLOC_ALIGN_MASK + 1);
|
||||||
return (ref.offset | A::tag);
|
return (offset | A::tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
@@ -56,16 +56,28 @@ public:
|
|||||||
|
|
||||||
enum DB_scope_mode {READER_SCOPE, WRITER_SCOPE};
|
enum DB_scope_mode {READER_SCOPE, WRITER_SCOPE};
|
||||||
|
|
||||||
|
typedef size_t txn_t;
|
||||||
|
|
||||||
class PgfDB {
|
class PgfDB {
|
||||||
private:
|
private:
|
||||||
int fd;
|
int fd;
|
||||||
const char *filepath;
|
const char *filepath;
|
||||||
malloc_state* ms;
|
malloc_state* ms;
|
||||||
size_t mmap_size;
|
unsigned char* base;
|
||||||
|
|
||||||
|
// The following four fields are normally equal to
|
||||||
|
// the corresponding fields in the malloc_state.
|
||||||
|
// The exception is when a transaction is active.
|
||||||
|
object top;
|
||||||
|
object free_blocks;
|
||||||
|
object free_descriptors[2];
|
||||||
|
|
||||||
|
size_t mmap_size;
|
||||||
|
size_t page_size;
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
pthread_rwlock_t *rwlock;
|
pid_t pid;
|
||||||
#else
|
#else
|
||||||
|
DWORD pid;
|
||||||
HANDLE hMap;
|
HANDLE hMap;
|
||||||
HANDLE hRWEvent;
|
HANDLE hRWEvent;
|
||||||
#endif
|
#endif
|
||||||
@@ -80,48 +92,60 @@ public:
|
|||||||
PGF_INTERNAL_DECL PgfDB(const char* filepath, int flags, int mode);
|
PGF_INTERNAL_DECL PgfDB(const char* filepath, int flags, int mode);
|
||||||
PGF_INTERNAL_DECL ~PgfDB();
|
PGF_INTERNAL_DECL ~PgfDB();
|
||||||
|
|
||||||
|
PGF_INTERNAL_DECL static txn_t get_txn_id();
|
||||||
|
|
||||||
template<class A>
|
template<class A>
|
||||||
static ref<A> malloc(size_t extra_bytes=0) {
|
static ref<A> malloc(size_t extra_bytes=0) {
|
||||||
return current_db->malloc_internal(sizeof(A)+extra_bytes);
|
return current_db->malloc_internal(sizeof(A)+extra_bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class A>
|
template<class A>
|
||||||
static ref<A> realloc(ref<A> r, size_t extra_bytes) {
|
static ref<A> realloc(ref<A> r, size_t old_extra_bytes, size_t new_extra_bytes) {
|
||||||
return current_db->realloc_internal(r.as_object(), sizeof(A)+extra_bytes);
|
return current_db->realloc_internal(r.as_object(), sizeof(A)+old_extra_bytes, sizeof(A)+new_extra_bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class A>
|
template<class A>
|
||||||
static void free(ref<A> o) {
|
static void free(ref<A> o, size_t extra_bytes=0) {
|
||||||
current_db->free_internal(o.as_object());
|
current_db->free_internal(o.as_object(), sizeof(A)+extra_bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
PGF_INTERNAL_DECL void cleanup_revisions();
|
PGF_INTERNAL_DECL void cleanup_revisions();
|
||||||
|
|
||||||
static PGF_INTERNAL_DECL ref<PgfPGF> get_revision(PgfText *name);
|
PGF_INTERNAL_DECL object get_active_revision();
|
||||||
static PGF_INTERNAL_DECL void set_revision(ref<PgfPGF> pgf);
|
PGF_INTERNAL_DECL void set_active_revision(object o);
|
||||||
|
PGF_INTERNAL_DECL void register_revision(object o);
|
||||||
|
PGF_INTERNAL_DECL void unregister_revision(object o);
|
||||||
|
|
||||||
static PGF_INTERNAL_DECL ref<PgfPGF> revision2pgf(PgfRevision revision);
|
PGF_INTERNAL_DECL ref<PgfPGF> revision2pgf(PgfRevision revision);
|
||||||
static PGF_INTERNAL_DECL bool is_persistant_revision(ref<PgfPGF> pgf);
|
PGF_INTERNAL_DECL ref<PgfConcr> revision2concr(PgfConcrRevision revision);
|
||||||
static PGF_INTERNAL_DECL void link_transient_revision(ref<PgfPGF> pgf);
|
|
||||||
static PGF_INTERNAL_DECL void unlink_transient_revision(ref<PgfPGF> pgf);
|
|
||||||
|
|
||||||
static PGF_INTERNAL_DECL ref<PgfConcr> revision2concr(PgfConcrRevision revision);
|
PGF_INTERNAL_DECL void start_transaction();
|
||||||
static PGF_INTERNAL_DECL bool is_persistant_revision(ref<PgfConcr> concr);
|
PGF_INTERNAL_DECL void commit();
|
||||||
static PGF_INTERNAL_DECL void link_transient_revision(ref<PgfConcr> concr);
|
PGF_INTERNAL_DECL void rollback();
|
||||||
static PGF_INTERNAL_DECL void unlink_transient_revision(ref<PgfConcr> concr);
|
|
||||||
|
|
||||||
static PGF_INTERNAL_DECL void sync();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PGF_INTERNAL_DECL void init_state(size_t size);
|
PGF_INTERNAL_DECL int init_state();
|
||||||
|
|
||||||
|
PGF_INTERNAL_DECL size_t block_descr_size(object map);
|
||||||
|
PGF_INTERNAL_DECL object new_block_descr(object o, size_t size);
|
||||||
|
PGF_INTERNAL_DECL object upd_block_descr(object map, object left, object right);
|
||||||
|
PGF_INTERNAL_DECL object balanceL_block_descriptor(object map);
|
||||||
|
PGF_INTERNAL_DECL object balanceR_block_descriptor(object map);
|
||||||
|
PGF_INTERNAL_DECL object pop_first_block_descriptor(object map, object *res);
|
||||||
|
PGF_INTERNAL_DECL object pop_last_block_descriptor(object map, object *res);
|
||||||
|
PGF_INTERNAL_DECL object insert_block_descriptor(object map, object o, size_t size);
|
||||||
|
PGF_INTERNAL_DECL object delete_block_descriptor(object map, size_t *psize, object *po);
|
||||||
|
|
||||||
|
#ifdef DEBUG_MEMORY_ALLOCATOR
|
||||||
|
PGF_INTERNAL_DECL void dump_free_blocks(object map);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
PGF_INTERNAL_DECL object malloc_internal(size_t bytes);
|
PGF_INTERNAL_DECL object malloc_internal(size_t bytes);
|
||||||
PGF_INTERNAL_DECL object realloc_internal(object oldo, size_t bytes);
|
|
||||||
|
|
||||||
PGF_INTERNAL_DECL void free_internal(object o);
|
PGF_INTERNAL_DECL object realloc_internal(object oldo, size_t old_bytes, size_t new_bytes);
|
||||||
|
|
||||||
PGF_INTERNAL_DECL void register_process();
|
PGF_INTERNAL_DECL void free_internal(object o, size_t bytes);
|
||||||
PGF_INTERNAL_DECL void unregister_process();
|
|
||||||
|
|
||||||
PGF_INTERNAL_DECL void lock(DB_scope_mode m);
|
PGF_INTERNAL_DECL void lock(DB_scope_mode m);
|
||||||
PGF_INTERNAL_DECL void unlock();
|
PGF_INTERNAL_DECL void unlock();
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ PgfExpr PgfDBUnmarshaller::eabs(PgfBindType bind_type, PgfText *name, PgfExpr bo
|
|||||||
eabs->bind_type = bind_type;
|
eabs->bind_type = bind_type;
|
||||||
eabs->body = m->match_expr(this, body);
|
eabs->body = m->match_expr(this, body);
|
||||||
memcpy(&eabs->name, name, sizeof(PgfText)+name->size+1);
|
memcpy(&eabs->name, name, sizeof(PgfText)+name->size+1);
|
||||||
return ref<PgfExprAbs>::tagged(eabs);
|
return eabs.tagged();
|
||||||
}
|
}
|
||||||
|
|
||||||
PgfExpr PgfDBUnmarshaller::eapp(PgfExpr fun, PgfExpr arg)
|
PgfExpr PgfDBUnmarshaller::eapp(PgfExpr fun, PgfExpr arg)
|
||||||
@@ -124,21 +124,21 @@ PgfExpr PgfDBUnmarshaller::eapp(PgfExpr fun, PgfExpr arg)
|
|||||||
ref<PgfExprApp> eapp = PgfDB::malloc<PgfExprApp>();
|
ref<PgfExprApp> eapp = PgfDB::malloc<PgfExprApp>();
|
||||||
eapp->fun = m->match_expr(this, fun);
|
eapp->fun = m->match_expr(this, fun);
|
||||||
eapp->arg = m->match_expr(this, arg);
|
eapp->arg = m->match_expr(this, arg);
|
||||||
return ref<PgfExprApp>::tagged(eapp);
|
return eapp.tagged();
|
||||||
}
|
}
|
||||||
|
|
||||||
PgfExpr PgfDBUnmarshaller::elit(PgfLiteral lit)
|
PgfExpr PgfDBUnmarshaller::elit(PgfLiteral lit)
|
||||||
{
|
{
|
||||||
ref<PgfExprLit> elit = PgfDB::malloc<PgfExprLit>();
|
ref<PgfExprLit> elit = PgfDB::malloc<PgfExprLit>();
|
||||||
elit->lit = m->match_lit(this, lit);
|
elit->lit = m->match_lit(this, lit);
|
||||||
return ref<PgfExprLit>::tagged(elit);
|
return elit.tagged();
|
||||||
}
|
}
|
||||||
|
|
||||||
PgfExpr PgfDBUnmarshaller::emeta(PgfMetaId meta_id)
|
PgfExpr PgfDBUnmarshaller::emeta(PgfMetaId meta_id)
|
||||||
{
|
{
|
||||||
ref<PgfExprMeta> emeta = PgfDB::malloc<PgfExprMeta>();
|
ref<PgfExprMeta> emeta = PgfDB::malloc<PgfExprMeta>();
|
||||||
emeta->id = meta_id;
|
emeta->id = meta_id;
|
||||||
return ref<PgfExprMeta>::tagged(emeta);
|
return emeta.tagged();
|
||||||
}
|
}
|
||||||
|
|
||||||
PgfExpr PgfDBUnmarshaller::efun(PgfText *name)
|
PgfExpr PgfDBUnmarshaller::efun(PgfText *name)
|
||||||
@@ -146,14 +146,14 @@ PgfExpr PgfDBUnmarshaller::efun(PgfText *name)
|
|||||||
ref<PgfExprFun> efun =
|
ref<PgfExprFun> efun =
|
||||||
PgfDB::malloc<PgfExprFun>(name->size+1);
|
PgfDB::malloc<PgfExprFun>(name->size+1);
|
||||||
memcpy(&efun->name, name, sizeof(PgfText)+name->size+1);
|
memcpy(&efun->name, name, sizeof(PgfText)+name->size+1);
|
||||||
return ref<PgfExprFun>::tagged(efun);
|
return efun.tagged();
|
||||||
}
|
}
|
||||||
|
|
||||||
PgfExpr PgfDBUnmarshaller::evar(int index)
|
PgfExpr PgfDBUnmarshaller::evar(int index)
|
||||||
{
|
{
|
||||||
ref<PgfExprVar> evar = PgfDB::malloc<PgfExprVar>();
|
ref<PgfExprVar> evar = PgfDB::malloc<PgfExprVar>();
|
||||||
evar->var = index;
|
evar->var = index;
|
||||||
return ref<PgfExprVar>::tagged(evar);
|
return evar.tagged();
|
||||||
}
|
}
|
||||||
|
|
||||||
PgfExpr PgfDBUnmarshaller::etyped(PgfExpr expr, PgfType ty)
|
PgfExpr PgfDBUnmarshaller::etyped(PgfExpr expr, PgfType ty)
|
||||||
@@ -161,14 +161,14 @@ PgfExpr PgfDBUnmarshaller::etyped(PgfExpr expr, PgfType ty)
|
|||||||
ref<PgfExprTyped> etyped = PgfDB::malloc<PgfExprTyped>();
|
ref<PgfExprTyped> etyped = PgfDB::malloc<PgfExprTyped>();
|
||||||
etyped->expr = m->match_expr(this, expr);
|
etyped->expr = m->match_expr(this, expr);
|
||||||
etyped->type = m->match_type(this, ty);
|
etyped->type = m->match_type(this, ty);
|
||||||
return ref<PgfExprTyped>::tagged(etyped);
|
return etyped.tagged();
|
||||||
}
|
}
|
||||||
|
|
||||||
PgfExpr PgfDBUnmarshaller::eimplarg(PgfExpr expr)
|
PgfExpr PgfDBUnmarshaller::eimplarg(PgfExpr expr)
|
||||||
{
|
{
|
||||||
ref<PgfExprImplArg> eimpl = current_db->malloc<PgfExprImplArg>();
|
ref<PgfExprImplArg> eimpl = current_db->malloc<PgfExprImplArg>();
|
||||||
eimpl->expr = m->match_expr(this, expr);
|
eimpl->expr = m->match_expr(this, expr);
|
||||||
return ref<PgfExprImplArg>::tagged(eimpl);
|
return eimpl.tagged();
|
||||||
}
|
}
|
||||||
|
|
||||||
PgfLiteral PgfDBUnmarshaller::lint(size_t size, uintmax_t *val)
|
PgfLiteral PgfDBUnmarshaller::lint(size_t size, uintmax_t *val)
|
||||||
@@ -177,14 +177,14 @@ PgfLiteral PgfDBUnmarshaller::lint(size_t size, uintmax_t *val)
|
|||||||
PgfDB::malloc<PgfLiteralInt>(size*sizeof(uintmax_t));
|
PgfDB::malloc<PgfLiteralInt>(size*sizeof(uintmax_t));
|
||||||
lit_int->size = size;
|
lit_int->size = size;
|
||||||
memcpy(&lit_int->val, val, size*sizeof(uintmax_t));
|
memcpy(&lit_int->val, val, size*sizeof(uintmax_t));
|
||||||
return ref<PgfLiteralInt>::tagged(lit_int);
|
return lit_int.tagged();
|
||||||
}
|
}
|
||||||
|
|
||||||
PgfLiteral PgfDBUnmarshaller::lflt(double val)
|
PgfLiteral PgfDBUnmarshaller::lflt(double val)
|
||||||
{
|
{
|
||||||
ref<PgfLiteralFlt> lit_flt = PgfDB::malloc<PgfLiteralFlt>();
|
ref<PgfLiteralFlt> lit_flt = PgfDB::malloc<PgfLiteralFlt>();
|
||||||
lit_flt->val = val;
|
lit_flt->val = val;
|
||||||
return ref<PgfLiteralFlt>::tagged(lit_flt);
|
return lit_flt.tagged();
|
||||||
}
|
}
|
||||||
|
|
||||||
PgfLiteral PgfDBUnmarshaller::lstr(PgfText *val)
|
PgfLiteral PgfDBUnmarshaller::lstr(PgfText *val)
|
||||||
@@ -192,7 +192,7 @@ PgfLiteral PgfDBUnmarshaller::lstr(PgfText *val)
|
|||||||
ref<PgfLiteralStr> lit_str =
|
ref<PgfLiteralStr> lit_str =
|
||||||
PgfDB::malloc<PgfLiteralStr>(val->size+1);
|
PgfDB::malloc<PgfLiteralStr>(val->size+1);
|
||||||
memcpy(&lit_str->val, val, sizeof(PgfText)+val->size+1);
|
memcpy(&lit_str->val, val, sizeof(PgfText)+val->size+1);
|
||||||
return ref<PgfLiteralStr>::tagged(lit_str);
|
return lit_str.tagged();
|
||||||
}
|
}
|
||||||
|
|
||||||
PgfType PgfDBUnmarshaller::dtyp(size_t n_hypos, PgfTypeHypo *hypos,
|
PgfType PgfDBUnmarshaller::dtyp(size_t n_hypos, PgfTypeHypo *hypos,
|
||||||
@@ -217,9 +217,8 @@ PgfType PgfDBUnmarshaller::dtyp(size_t n_hypos, PgfTypeHypo *hypos,
|
|||||||
return ty.as_object();
|
return ty.as_object();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PgfDBUnmarshaller::free_ref(object x)
|
void PgfDBUnmarshaller::free_ref(object expr)
|
||||||
{
|
{
|
||||||
PgfDB::free(ref<void>::untagged(x));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PgfLiteral PgfInternalMarshaller::match_lit(PgfUnmarshaller *u, PgfLiteral l)
|
PgfLiteral PgfInternalMarshaller::match_lit(PgfUnmarshaller *u, PgfLiteral l)
|
||||||
@@ -1170,11 +1169,12 @@ void PgfExprProbEstimator::free_ref(object x)
|
|||||||
}
|
}
|
||||||
|
|
||||||
PGF_INTERNAL
|
PGF_INTERNAL
|
||||||
void pgf_literal_free(PgfLiteral literal)
|
void pgf_literal_release(PgfLiteral literal)
|
||||||
{
|
{
|
||||||
switch (ref<PgfLiteral>::get_tag(literal)) {
|
switch (ref<PgfLiteral>::get_tag(literal)) {
|
||||||
case PgfLiteralInt::tag: {
|
case PgfLiteralInt::tag: {
|
||||||
PgfDB::free(ref<PgfLiteralInt>::untagged(literal));
|
auto lint = ref<PgfLiteralInt>::untagged(literal);
|
||||||
|
PgfDB::free(lint, lint->size*sizeof(uintmax_t));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PgfLiteralFlt::tag: {
|
case PgfLiteralFlt::tag: {
|
||||||
@@ -1182,7 +1182,8 @@ void pgf_literal_free(PgfLiteral literal)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PgfLiteralStr::tag: {
|
case PgfLiteralStr::tag: {
|
||||||
PgfDB::free(ref<PgfLiteralStr>::untagged(literal));
|
auto lstr = ref<PgfLiteralStr>::untagged(literal);
|
||||||
|
PgfDB::free(lstr, lstr->val.size+1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@@ -1191,25 +1192,25 @@ void pgf_literal_free(PgfLiteral literal)
|
|||||||
}
|
}
|
||||||
|
|
||||||
PGF_INTERNAL
|
PGF_INTERNAL
|
||||||
void pgf_expr_free(PgfExpr expr)
|
void pgf_expr_release(PgfExpr expr)
|
||||||
{
|
{
|
||||||
switch (ref<PgfExpr>::get_tag(expr)) {
|
switch (ref<PgfExpr>::get_tag(expr)) {
|
||||||
case PgfExprAbs::tag: {
|
case PgfExprAbs::tag: {
|
||||||
auto eabs = ref<PgfExprAbs>::untagged(expr);
|
auto eabs = ref<PgfExprAbs>::untagged(expr);
|
||||||
pgf_expr_free(eabs->body);
|
pgf_expr_release(eabs->body);
|
||||||
PgfDB::free(eabs);
|
PgfDB::free(eabs, eabs->name.size+1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PgfExprApp::tag: {
|
case PgfExprApp::tag: {
|
||||||
auto eapp = ref<PgfExprApp>::untagged(expr);
|
auto eapp = ref<PgfExprApp>::untagged(expr);
|
||||||
pgf_expr_free(eapp->fun);
|
pgf_expr_release(eapp->fun);
|
||||||
pgf_expr_free(eapp->arg);
|
pgf_expr_release(eapp->arg);
|
||||||
PgfDB::free(eapp);
|
PgfDB::free(eapp);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PgfExprLit::tag: {
|
case PgfExprLit::tag: {
|
||||||
auto elit = ref<PgfExprLit>::untagged(expr);
|
auto elit = ref<PgfExprLit>::untagged(expr);
|
||||||
pgf_literal_free(elit->lit);
|
pgf_literal_release(elit->lit);
|
||||||
PgfDB::free(elit);
|
PgfDB::free(elit);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1218,7 +1219,8 @@ void pgf_expr_free(PgfExpr expr)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PgfExprFun::tag: {
|
case PgfExprFun::tag: {
|
||||||
PgfDB::free(ref<PgfExprFun>::untagged(expr));
|
auto efun = ref<PgfExprFun>::untagged(expr);
|
||||||
|
PgfDB::free(efun, efun->name.size+1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PgfExprVar::tag: {
|
case PgfExprVar::tag: {
|
||||||
@@ -1227,14 +1229,14 @@ void pgf_expr_free(PgfExpr expr)
|
|||||||
}
|
}
|
||||||
case PgfExprTyped::tag: {
|
case PgfExprTyped::tag: {
|
||||||
auto etyped = ref<PgfExprTyped>::untagged(expr);
|
auto etyped = ref<PgfExprTyped>::untagged(expr);
|
||||||
pgf_expr_free(etyped->expr);
|
pgf_expr_release(etyped->expr);
|
||||||
pgf_type_free(etyped->type);
|
pgf_type_release(etyped->type);
|
||||||
PgfDB::free(etyped);
|
PgfDB::free(etyped);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PgfExprImplArg::tag: {
|
case PgfExprImplArg::tag: {
|
||||||
auto eimpl = ref<PgfExprImplArg>::untagged(expr);
|
auto eimpl = ref<PgfExprImplArg>::untagged(expr);
|
||||||
pgf_expr_free(eimpl->expr);
|
pgf_expr_release(eimpl->expr);
|
||||||
PgfDB::free(eimpl);
|
PgfDB::free(eimpl);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1244,25 +1246,25 @@ void pgf_expr_free(PgfExpr expr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
PGF_INTERNAL
|
PGF_INTERNAL
|
||||||
void pgf_context_free(ref<Vector<PgfHypo>> hypos)
|
void pgf_context_release(ref<Vector<PgfHypo>> hypos)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < hypos->len; i++) {
|
for (size_t i = 0; i < hypos->len; i++) {
|
||||||
PgfDB::free(vector_elem(hypos, i)->cid);
|
text_db_release(vector_elem(hypos, i)->cid);
|
||||||
pgf_type_free(vector_elem(hypos, i)->type);
|
pgf_type_release(vector_elem(hypos, i)->type);
|
||||||
}
|
}
|
||||||
|
|
||||||
PgfDB::free(hypos);
|
Vector<PgfHypo>::release(hypos);
|
||||||
}
|
}
|
||||||
|
|
||||||
PGF_INTERNAL
|
PGF_INTERNAL
|
||||||
void pgf_type_free(ref<PgfDTyp> dtyp)
|
void pgf_type_release(ref<PgfDTyp> dtyp)
|
||||||
{
|
{
|
||||||
pgf_context_free(dtyp->hypos);
|
pgf_context_release(dtyp->hypos);
|
||||||
|
|
||||||
for (size_t i = 0; i < dtyp->exprs->len; i++) {
|
for (size_t i = 0; i < dtyp->exprs->len; i++) {
|
||||||
pgf_expr_free(*vector_elem(dtyp->exprs, i));
|
pgf_expr_release(*vector_elem(dtyp->exprs, i));
|
||||||
}
|
}
|
||||||
PgfDB::free(dtyp->exprs);
|
Vector<PgfExpr>::release(dtyp->exprs);
|
||||||
|
|
||||||
PgfDB::free(dtyp);
|
PgfDB::free(dtyp, dtyp->name.size+1);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -228,15 +228,15 @@ public:
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
PGF_INTERNAL_DECL
|
PGF_INTERNAL_DECL
|
||||||
void pgf_literal_free(PgfLiteral literal);
|
void pgf_literal_release(PgfLiteral literal);
|
||||||
|
|
||||||
PGF_INTERNAL_DECL
|
PGF_INTERNAL_DECL
|
||||||
void pgf_expr_free(PgfExpr expr);
|
void pgf_expr_release(PgfExpr expr);
|
||||||
|
|
||||||
PGF_INTERNAL_DECL
|
PGF_INTERNAL_DECL
|
||||||
void pgf_context_free(ref<Vector<PgfHypo>> hypos);
|
void pgf_context_release(ref<Vector<PgfHypo>> hypos);
|
||||||
|
|
||||||
PGF_INTERNAL_DECL
|
PGF_INTERNAL_DECL
|
||||||
void pgf_type_free(ref<PgfDTyp> dtyp);
|
void pgf_type_release(ref<PgfDTyp> dtyp);
|
||||||
|
|
||||||
#endif /* EXPR_H_ */
|
#endif /* EXPR_H_ */
|
||||||
|
|||||||
@@ -5,15 +5,8 @@
|
|||||||
|
|
||||||
// #define DEBUG_NAMESPACE
|
// #define DEBUG_NAMESPACE
|
||||||
|
|
||||||
/* Namespace<V> expects that the class V contains:
|
/* Namespace<V> expects that the class V contains,
|
||||||
*
|
* a member 'PgfText name' which contains the name of the object.
|
||||||
* - A member 'size_t ref_count' which keeps track of the number of
|
|
||||||
* references to the particular object.
|
|
||||||
* - A member 'PgfText name' which contains the name of the object.
|
|
||||||
* - A method:
|
|
||||||
* static void release(ref<V> object)
|
|
||||||
* which is executed when ref_count becomes zero. After that the memory
|
|
||||||
* for the object is released as well.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
template <class V>
|
template <class V>
|
||||||
@@ -26,7 +19,7 @@ template <class V>
|
|||||||
class PGF_INTERNAL_DECL Node
|
class PGF_INTERNAL_DECL Node
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
size_t ref_count;
|
txn_t txn_id;
|
||||||
|
|
||||||
size_t sz;
|
size_t sz;
|
||||||
V value;
|
V value;
|
||||||
@@ -36,12 +29,12 @@ public:
|
|||||||
static
|
static
|
||||||
ref<Node> new_node(V value)
|
ref<Node> new_node(V value)
|
||||||
{
|
{
|
||||||
ref<Node> node = current_db->malloc<Node>();
|
ref<Node> node = PgfDB::malloc<Node>();
|
||||||
node->ref_count = 1;
|
node->txn_id = PgfDB::get_txn_id();
|
||||||
node->sz = 1;
|
node->sz = 1;
|
||||||
node->value = value;
|
node->value = value;
|
||||||
node->left = 0;
|
node->left = 0;
|
||||||
node->right = 0;
|
node->right = 0;
|
||||||
|
|
||||||
#ifdef DEBUG_NAMESPACE
|
#ifdef DEBUG_NAMESPACE
|
||||||
printf("new node %6ld %s\n", node.as_object(), node->value->name.text);
|
printf("new node %6ld %s\n", node.as_object(), node->value->name.text);
|
||||||
@@ -50,310 +43,200 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
ref<Node> new_node(V value, ref<Node> left, ref<Node> right)
|
ref<Node> upd_node(ref<Node> node, ref<Node> left, ref<Node> right)
|
||||||
{
|
{
|
||||||
ref<Node> node = current_db->malloc<Node>();
|
if (node->txn_id != PgfDB::get_txn_id()) {
|
||||||
node->ref_count = 1;
|
ref<Node> new_node = PgfDB::malloc<Node>();
|
||||||
node->sz = 1+Node::size(left)+Node::size(right);
|
new_node->txn_id = PgfDB::get_txn_id();
|
||||||
node->value = value;
|
new_node->value = node->value;
|
||||||
node->left = left;
|
release(node);
|
||||||
node->right = right;
|
node = new_node;
|
||||||
|
|
||||||
#ifdef DEBUG_NAMESPACE
|
#ifdef DEBUG_NAMESPACE
|
||||||
printf("new node %6ld %s(%ld,%ld)\n", node.as_object(), node->value->name.text, left.as_object(), right.as_object());
|
printf("new node %6ld %s(%ld,%ld)\n", node.as_object(), node->value->name.text, left.as_object(), right.as_object());
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
node->sz = 1+Node::size(left)+Node::size(right);
|
||||||
|
node->left = left;
|
||||||
|
node->right = right;
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
void add_node_ref(ref<Node> node)
|
ref<Node> balanceL(ref<Node> node)
|
||||||
{
|
{
|
||||||
node->ref_count++;
|
if (node->right == 0) {
|
||||||
#ifdef DEBUG_NAMESPACE
|
if (node->left == 0) {
|
||||||
printf("add_ref node %6ld %s (ref_count=%ld)\n", node.as_object(), node->value->name.text, node->ref_count);
|
return node;
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class A> static
|
|
||||||
void add_value_ref(A &value)
|
|
||||||
{
|
|
||||||
value.add_ref();
|
|
||||||
#ifdef DEBUG_NAMESPACE
|
|
||||||
printf("add_ref value %5ld %s (ref_count=%ld)\n", value.as_object(), value->name.text, value->ref_count);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class A> static
|
|
||||||
void add_value_ref(ref<A> value)
|
|
||||||
{
|
|
||||||
value->ref_count++;
|
|
||||||
#ifdef DEBUG_NAMESPACE
|
|
||||||
printf("add_ref value %5ld %s (ref_count=%ld)\n", value.as_object(), value->name.text, value->ref_count);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class A> static
|
|
||||||
void release_value_ref(A &value)
|
|
||||||
{
|
|
||||||
#ifdef DEBUG_NAMESPACE
|
|
||||||
printf("release value %5ld %s (ref_count=%ld)\n", value.as_object(), value->name.text, value->ref_count-1);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
value.release_ref();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class A> static
|
|
||||||
void release_value_ref(ref<A> value)
|
|
||||||
{
|
|
||||||
#ifdef DEBUG_NAMESPACE
|
|
||||||
printf("release value %5ld %s (ref_count=%ld)\n", value.as_object(), value->name.text, value->ref_count-1);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!(--value->ref_count)) {
|
|
||||||
A::release(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static
|
|
||||||
ref<Node> balanceL(V value, ref<Node> left, ref<Node> right)
|
|
||||||
{
|
|
||||||
if (right == 0) {
|
|
||||||
if (left == 0) {
|
|
||||||
add_value_ref(value);
|
|
||||||
return new_node(value);
|
|
||||||
} else {
|
} else {
|
||||||
if (left->left == 0) {
|
if (node->left->left == 0) {
|
||||||
if (left->right == 0) {
|
if (node->left->right == 0) {
|
||||||
add_value_ref(value);
|
return node;
|
||||||
add_node_ref(left);
|
|
||||||
return new_node(value,left,0);
|
|
||||||
} else {
|
} else {
|
||||||
add_value_ref(value);
|
ref<Node<V>> left_right = node->left->right;
|
||||||
add_value_ref(left->value);
|
ref<Node<V>> left = upd_node(node->left,0,0);
|
||||||
add_value_ref(left->right->value);
|
ref<Node<V>> right = upd_node(node,0,0);
|
||||||
ref<Node<V>> new_left = new_node(left->value);
|
return upd_node(left_right,
|
||||||
ref<Node<V>> new_right = new_node(value);
|
left,
|
||||||
return new_node(left->right->value,
|
right);
|
||||||
new_left,
|
|
||||||
new_right);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (left->right == 0) {
|
if (node->left->right == 0) {
|
||||||
add_value_ref(value);
|
ref<Node<V>> left = node->left;
|
||||||
ref<Node<V>> new_right = new_node(value);
|
ref<Node<V>> right = upd_node(node,0,0);
|
||||||
add_value_ref(left->value);
|
return upd_node(left,
|
||||||
add_node_ref(left->left);
|
|
||||||
return new_node(left->value,
|
|
||||||
left->left,
|
left->left,
|
||||||
new_right);
|
right);
|
||||||
} else {
|
} else {
|
||||||
if (left->right->sz < 2 * left->left->sz) {
|
if (node->left->right->sz < 2 * node->left->left->sz) {
|
||||||
add_value_ref(value);
|
ref<Node<V>> left = node->left;
|
||||||
add_value_ref(left->value);
|
ref<Node<V>> right =
|
||||||
add_node_ref(left->left);
|
upd_node(node,
|
||||||
add_node_ref(left->right);
|
|
||||||
ref<Node<V>> new_right =
|
|
||||||
new_node(value,
|
|
||||||
left->right,
|
left->right,
|
||||||
0);
|
0);
|
||||||
return new_node(left->value,
|
return upd_node(left,
|
||||||
left->left,
|
left->left,
|
||||||
new_right);
|
right);
|
||||||
} else {
|
} else {
|
||||||
add_value_ref(value);
|
ref<Node<V>> left_right = node->left->right;
|
||||||
add_value_ref(left->value);
|
ref<Node<V>> left =
|
||||||
add_value_ref(left->right->value);
|
upd_node(node->left,
|
||||||
add_node_ref(left->left);
|
node->left->left,
|
||||||
if (left->right->left != 0)
|
left_right->left);
|
||||||
add_node_ref(left->right->left);
|
ref<Node<V>> right =
|
||||||
if (left->right->right != 0)
|
upd_node(node,
|
||||||
add_node_ref(left->right->right);
|
left_right->right,
|
||||||
ref<Node<V>> new_left =
|
|
||||||
new_node(left->value,
|
|
||||||
left->left,
|
|
||||||
left->right->left);
|
|
||||||
ref<Node<V>> new_right =
|
|
||||||
new_node(value,
|
|
||||||
left->right->right,
|
|
||||||
0);
|
0);
|
||||||
return new_node(left->right->value,
|
return upd_node(left_right,
|
||||||
new_left,
|
left,
|
||||||
new_right);
|
right);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (left == 0) {
|
if (node->left == 0) {
|
||||||
add_value_ref(value);
|
return node;
|
||||||
add_node_ref(right);
|
|
||||||
return new_node(value,0,right);
|
|
||||||
} else {
|
} else {
|
||||||
if (left->sz > 3*right->sz) {
|
if (node->left->sz > 3*node->right->sz) {
|
||||||
if (left->right->sz < 2*left->left->sz) {
|
if (node->left->right->sz < 2*node->left->left->sz) {
|
||||||
add_value_ref(value);
|
ref<Node<V>> left = node->left;
|
||||||
add_value_ref(left->value);
|
ref<Node<V>> right =
|
||||||
add_node_ref(left->left);
|
upd_node(node,
|
||||||
add_node_ref(left->right);
|
|
||||||
add_node_ref(right);
|
|
||||||
ref<Node<V>> new_right =
|
|
||||||
new_node(value,
|
|
||||||
left->right,
|
left->right,
|
||||||
right);
|
node->right);
|
||||||
return new_node(left->value,
|
return upd_node(left,
|
||||||
left->left,
|
left->left,
|
||||||
new_right);
|
right);
|
||||||
} else {
|
} else {
|
||||||
add_value_ref(value);
|
ref<Node<V>> left_right = node->left->right;
|
||||||
add_value_ref(left->value);
|
ref<Node<V>> left =
|
||||||
add_value_ref(left->right->value);
|
upd_node(node->left,
|
||||||
add_node_ref(left->left);
|
node->left->left,
|
||||||
if (left->right->left != 0)
|
left_right->left);
|
||||||
add_node_ref(left->right->left);
|
ref<Node<V>> right =
|
||||||
if (left->right->right != 0)
|
upd_node(node,
|
||||||
add_node_ref(left->right->right);
|
left_right->right,
|
||||||
add_node_ref(right);
|
node->right);
|
||||||
ref<Node<V>> new_left =
|
return upd_node(left_right,
|
||||||
new_node(left->value,
|
left,
|
||||||
left->left,
|
right);
|
||||||
left->right->left);
|
|
||||||
ref<Node<V>> new_right =
|
|
||||||
new_node(value,
|
|
||||||
left->right->right,
|
|
||||||
right);
|
|
||||||
return new_node(left->right->value,
|
|
||||||
new_left,
|
|
||||||
new_right);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
add_value_ref(value);
|
return node;
|
||||||
add_node_ref(left);
|
|
||||||
add_node_ref(right);
|
|
||||||
return new_node(value,left,right);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
ref<Node> balanceR(V value, ref<Node> left, ref<Node> right)
|
ref<Node> balanceR(ref<Node> node)
|
||||||
{
|
{
|
||||||
if (left == 0) {
|
if (node->left == 0) {
|
||||||
if (right == 0) {
|
if (node->right == 0) {
|
||||||
add_value_ref(value);
|
return node;
|
||||||
return new_node(value);
|
|
||||||
} else {
|
} else {
|
||||||
if (right->left == 0) {
|
if (node->right->left == 0) {
|
||||||
if (right->right == 0) {
|
if (node->right->right == 0) {
|
||||||
add_value_ref(value);
|
return node;
|
||||||
add_node_ref(right);
|
|
||||||
return new_node(value,0,right);
|
|
||||||
} else {
|
} else {
|
||||||
add_value_ref(value);
|
ref<Node<V>> right = node->right;
|
||||||
add_value_ref(right->value);
|
ref<Node<V>> left =
|
||||||
add_node_ref(right->right);
|
upd_node(node,
|
||||||
ref<Node<V>> new_left =
|
0,
|
||||||
new_node(value);
|
0);
|
||||||
return new_node(right->value,
|
return upd_node(right,
|
||||||
new_left,
|
left,
|
||||||
right->right);
|
right->right);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (right->right == 0) {
|
if (node->right->right == 0) {
|
||||||
add_value_ref(value);
|
ref<Node<V>> right_left = node->right->left;
|
||||||
add_value_ref(right->value);
|
ref<Node<V>> right =
|
||||||
add_value_ref(right->left->value);
|
upd_node(node->right,0,0);
|
||||||
ref<Node<V>> new_left =
|
ref<Node<V>> left =
|
||||||
new_node(value);
|
upd_node(node,0,0);
|
||||||
ref<Node<V>> new_right =
|
return upd_node(right_left,
|
||||||
new_node(right->value);
|
left,
|
||||||
return new_node(right->left->value,
|
right);
|
||||||
new_left,
|
|
||||||
new_right);
|
|
||||||
} else {
|
} else {
|
||||||
if (right->left->sz < 2 * right->right->sz) {
|
if (node->right->left->sz < 2 * node->right->right->sz) {
|
||||||
add_value_ref(value);
|
ref<Node<V>> right = node->right;
|
||||||
add_value_ref(right->value);
|
ref<Node<V>> left =
|
||||||
add_node_ref(right->left);
|
upd_node(node,
|
||||||
add_node_ref(right->right);
|
|
||||||
ref<Node<V>> new_left =
|
|
||||||
new_node(value,
|
|
||||||
0,
|
0,
|
||||||
right->left);
|
right->left);
|
||||||
return new_node(right->value,
|
return upd_node(right,
|
||||||
new_left,
|
left,
|
||||||
right->right);
|
right->right);
|
||||||
} else {
|
} else {
|
||||||
add_value_ref(value);
|
ref<Node<V>> right_left = node->right->left;
|
||||||
add_value_ref(right->value);
|
ref<Node<V>> right =
|
||||||
add_value_ref(right->left->value);
|
upd_node(node->right,
|
||||||
if (right->left->left != 0)
|
right_left->right,
|
||||||
add_node_ref(right->left->left);
|
node->right->right);
|
||||||
if (right->left->right != 0)
|
ref<Node<V>> left =
|
||||||
add_node_ref(right->left->right);
|
upd_node(node,
|
||||||
add_node_ref(right->right);
|
|
||||||
ref<Node<V>> new_left =
|
|
||||||
new_node(value,
|
|
||||||
0,
|
0,
|
||||||
right->left->left);
|
right_left->left);
|
||||||
ref<Node<V>> new_right =
|
return upd_node(right_left,
|
||||||
new_node(right->value,
|
left,
|
||||||
right->left->right,
|
right);
|
||||||
right->right);
|
|
||||||
return new_node(right->left->value,
|
|
||||||
new_left,
|
|
||||||
new_right);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (right == 0) {
|
if (node->right == 0) {
|
||||||
add_value_ref(value);
|
return node;
|
||||||
add_node_ref(left);
|
|
||||||
return new_node(value,left,0);
|
|
||||||
} else {
|
} else {
|
||||||
if (right->sz > 3*left->sz) {
|
if (node->right->sz > 3*node->left->sz) {
|
||||||
if (right->left->sz < 2*right->right->sz) {
|
if (node->right->left->sz < 2*node->right->right->sz) {
|
||||||
add_value_ref(value);
|
ref<Node<V>> right = node->right;
|
||||||
add_value_ref(right->value);
|
ref<Node<V>> left =
|
||||||
add_node_ref(left);
|
upd_node(node,
|
||||||
add_node_ref(right->left);
|
node->left,
|
||||||
add_node_ref(right->right);
|
|
||||||
ref<Node<V>> new_left =
|
|
||||||
new_node(value,
|
|
||||||
left,
|
|
||||||
right->left);
|
right->left);
|
||||||
return new_node(right->value,
|
return upd_node(right,
|
||||||
new_left,
|
left,
|
||||||
right->right);
|
right->right);
|
||||||
} else {
|
} else {
|
||||||
add_value_ref(value);
|
ref<Node<V>> right_left = node->right->left;
|
||||||
add_value_ref(right->value);
|
ref<Node<V>> right =
|
||||||
add_value_ref(right->left->value);
|
upd_node(node->right,
|
||||||
add_node_ref(left);
|
right_left->right,
|
||||||
if (right->left->left != 0)
|
node->right->right);
|
||||||
add_node_ref(right->left->left);
|
ref<Node<V>> left =
|
||||||
if (right->left->right != 0)
|
upd_node(node,
|
||||||
add_node_ref(right->left->right);
|
node->left,
|
||||||
add_node_ref(right->right);
|
right_left->left);
|
||||||
ref<Node<V>> new_left =
|
return upd_node(right_left,
|
||||||
new_node(value,
|
left,
|
||||||
left,
|
right);
|
||||||
right->left->left);
|
|
||||||
ref<Node<V>> new_right =
|
|
||||||
new_node(right->value,
|
|
||||||
right->left->right,
|
|
||||||
right->right);
|
|
||||||
return new_node(right->left->value,
|
|
||||||
new_left,
|
|
||||||
new_right);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
add_value_ref(value);
|
return node;
|
||||||
add_node_ref(left);
|
|
||||||
add_node_ref(right);
|
|
||||||
return new_node(value,left,right);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -368,57 +251,42 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
ref<Node> pop_first(ref<Node> node, V *res)
|
ref<Node> pop_first(ref<Node> node, ref<Node> *res)
|
||||||
{
|
{
|
||||||
if (node == 0) {
|
if (node == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
} else if (node->left == 0) {
|
} else if (node->left == 0) {
|
||||||
*res = node->value;
|
*res = node;
|
||||||
if (node->right != 0)
|
|
||||||
node->right->ref_count++;
|
|
||||||
return node->right;
|
return node->right;
|
||||||
} else {
|
} else {
|
||||||
ref<Node> new_left = pop_first(node->left, res);
|
ref<Node> left = pop_first(node->left, res);
|
||||||
ref<Node> new_node = balanceR(node->value, new_left, node->right);
|
ref<Node> node = upd_node(node, left, node->right);
|
||||||
release(new_left);
|
return balanceR(node);
|
||||||
return new_node;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
ref<Node> pop_last(ref<Node> node, V *res)
|
ref<Node> pop_last(ref<Node> node, ref<Node> *res)
|
||||||
{
|
{
|
||||||
if (node == 0) {
|
if (node == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
} else if (node->right == 0) {
|
} else if (node->right == 0) {
|
||||||
*res = node->value;
|
*res = node;
|
||||||
if (node->left != 0)
|
|
||||||
node->left->ref_count++;
|
|
||||||
return node->left;
|
return node->left;
|
||||||
} else {
|
} else {
|
||||||
ref<Node> new_right = pop_last(node->right, res);
|
ref<Node> right = pop_last(node->right, res);
|
||||||
ref<Node> new_node = balanceR(node->value, node->left, new_right);
|
ref<Node> node = upd_node(node, node->left, right);
|
||||||
release(new_right);
|
return balanceL(node);
|
||||||
return new_node;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
void release(ref<Node> node)
|
void release(ref<Node> node)
|
||||||
{
|
{
|
||||||
if (node == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
#ifdef DEBUG_NAMESPACE
|
#ifdef DEBUG_NAMESPACE
|
||||||
printf("release node %6ld %s (ref_count=%ld)\n", node.as_object(), node->value->name.text, node->ref_count-1);
|
printf("release node %6ld %s (ref_count=%ld)\n", node.as_object(), node->value->name.text, node->ref_count-1);
|
||||||
#endif
|
#endif
|
||||||
|
PgfDB::free(node);
|
||||||
if (!(--node->ref_count)) {
|
|
||||||
release(node->left);
|
|
||||||
release(node->right);
|
|
||||||
release_value_ref(node->value);
|
|
||||||
PgfDB::free(node);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -443,26 +311,22 @@ Namespace<V> namespace_insert(Namespace<V> map, ref<V> value)
|
|||||||
int cmp = textcmp(&value->name,&map->value->name);
|
int cmp = textcmp(&value->name,&map->value->name);
|
||||||
if (cmp < 0) {
|
if (cmp < 0) {
|
||||||
Namespace<V> left = namespace_insert(map->left, value);
|
Namespace<V> left = namespace_insert(map->left, value);
|
||||||
Namespace<V> node = Node<ref<V>>::balanceL(map->value,left,map->right);
|
map = Node<ref<V>>::upd_node(map,left,map->right);
|
||||||
namespace_release(left);
|
return Node<ref<V>>::balanceL(map);
|
||||||
return node;
|
|
||||||
} else if (cmp > 0) {
|
} else if (cmp > 0) {
|
||||||
Namespace<V> right = namespace_insert(map->right, value);
|
Namespace<V> right = namespace_insert(map->right, value);
|
||||||
Namespace<V> node = Node<ref<V>>::balanceR(map->value, map->left, right);
|
map = Node<ref<V>>::upd_node(map,map->left,right);
|
||||||
namespace_release(right);
|
return Node<ref<V>>::balanceR(map);
|
||||||
return node;
|
|
||||||
} else {
|
} else {
|
||||||
if (map->left != 0)
|
map = Node<ref<V>>::upd_node(map,map->left,map->right);
|
||||||
map->left->ref_count++;
|
map->value = value;
|
||||||
if (map->right != 0)
|
return map;
|
||||||
map->right->ref_count++;
|
|
||||||
return Node<ref<V>>::new_node(value,map->left,map->right);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class V>
|
template <class V>
|
||||||
Namespace<V> namespace_delete(Namespace<V> map, PgfText* name,
|
Namespace<V> namespace_delete(Namespace<V> map, PgfText* name,
|
||||||
ref<V> *pvalue = NULL)
|
ref<V> *pvalue)
|
||||||
{
|
{
|
||||||
if (map == 0) {
|
if (map == 0) {
|
||||||
if (pvalue != NULL) *pvalue = 0;
|
if (pvalue != NULL) *pvalue = 0;
|
||||||
@@ -472,41 +336,33 @@ Namespace<V> namespace_delete(Namespace<V> map, PgfText* name,
|
|||||||
int cmp = textcmp(name,&map->value->name);
|
int cmp = textcmp(name,&map->value->name);
|
||||||
if (cmp < 0) {
|
if (cmp < 0) {
|
||||||
Namespace<V> left = namespace_delete(map->left, name, pvalue);
|
Namespace<V> left = namespace_delete(map->left, name, pvalue);
|
||||||
if (left == map->left)
|
map = Node<ref<V>>::upd_node(map,left,map->right);
|
||||||
return map;
|
return Node<ref<V>>::balanceR(map);
|
||||||
Namespace<V> node = Node<ref<V>>::balanceR(map->value,left,map->right);
|
|
||||||
namespace_release(left);
|
|
||||||
return node;
|
|
||||||
} else if (cmp > 0) {
|
} else if (cmp > 0) {
|
||||||
Namespace<V> right = namespace_delete(map->right, name, pvalue);
|
Namespace<V> right = namespace_delete(map->right, name, pvalue);
|
||||||
if (right == map->right)
|
map = Node<ref<V>>::upd_node(map,map->left,right);
|
||||||
return map;
|
return Node<ref<V>>::balanceL(map);
|
||||||
Namespace<V> node = Node<ref<V>>::balanceL(map->value,map->left,right);
|
|
||||||
namespace_release(right);
|
|
||||||
return node;
|
|
||||||
} else {
|
} else {
|
||||||
if (pvalue != NULL) *pvalue = map->value;
|
if (pvalue != NULL) *pvalue = map->value;
|
||||||
|
|
||||||
if (map->left == 0) {
|
if (map->left == 0) {
|
||||||
if (map->right != 0)
|
Node<ref<V>>::release(map);
|
||||||
map->right->ref_count++;
|
|
||||||
return map->right;
|
return map->right;
|
||||||
} else if (map->right == 0) {
|
} else if (map->right == 0) {
|
||||||
if (map->left != 0)
|
Node<ref<V>>::release(map);
|
||||||
map->left->ref_count++;
|
|
||||||
return map->left;
|
return map->left;
|
||||||
} else if (map->left->sz > map->right->sz) {
|
} else if (map->left->sz > map->right->sz) {
|
||||||
ref<V> value;
|
Namespace<V> node;
|
||||||
Namespace<V> new_left = Node<ref<V>>::pop_last(map->left, &value);
|
Namespace<V> left = Node<ref<V>>::pop_last(map->left, &node);
|
||||||
Namespace<V> node = Node<ref<V>>::balanceR(value, new_left, map->right);
|
node = Node<ref<V>>::upd_node(node, left, map->right);
|
||||||
namespace_release(new_left);
|
Node<ref<V>>::release(map);
|
||||||
return node;
|
return Node<ref<V>>::balanceR(node);
|
||||||
} else {
|
} else {
|
||||||
ref<V> value;
|
Namespace<V> node;
|
||||||
Namespace<V> new_right = Node<ref<V>>::pop_first(map->right, &value);
|
Namespace<V> right = Node<ref<V>>::pop_first(map->right, &node);
|
||||||
Namespace<V> node = Node<ref<V>>::balanceL(value, map->left, new_right);
|
node = Node<ref<V>>::upd_node(node, map->left, right);
|
||||||
namespace_release(new_right);
|
Node<ref<V>>::release(map);
|
||||||
return node;
|
return Node<ref<V>>::balanceL(node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -554,6 +410,10 @@ void namespace_iter(Namespace<V> map, PgfItor* itor, PgfExn *err)
|
|||||||
template <class V>
|
template <class V>
|
||||||
void namespace_release(Namespace<V> node)
|
void namespace_release(Namespace<V> node)
|
||||||
{
|
{
|
||||||
|
if (node == 0)
|
||||||
|
return;
|
||||||
|
namespace_release(node->left);
|
||||||
|
namespace_release(node->right);
|
||||||
Node<ref<V>>::release(node);
|
Node<ref<V>>::release(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -462,18 +462,19 @@ void pgf_check_type(PgfDB *db, PgfRevision revision,
|
|||||||
PgfExn *err);
|
PgfExn *err);
|
||||||
|
|
||||||
PGF_API_DECL
|
PGF_API_DECL
|
||||||
PgfRevision pgf_clone_revision(PgfDB *db, PgfRevision revision,
|
PgfRevision pgf_start_transaction(PgfDB *db, PgfRevision revision,
|
||||||
PgfText *name,
|
|
||||||
PgfExn *err);
|
|
||||||
|
|
||||||
PGF_API_DECL
|
|
||||||
void pgf_commit_revision(PgfDB *db, PgfRevision revision,
|
|
||||||
PgfExn *err);
|
|
||||||
|
|
||||||
PGF_API_DECL
|
|
||||||
PgfRevision pgf_checkout_revision(PgfDB *db, PgfText *name,
|
|
||||||
PgfExn *err);
|
PgfExn *err);
|
||||||
|
|
||||||
|
PGF_API_DECL
|
||||||
|
void pgf_commit_transaction(PgfDB *db, PgfRevision revision,
|
||||||
|
PgfExn *err);
|
||||||
|
|
||||||
|
PGF_API_DECL
|
||||||
|
void pgf_rollback_transaction(PgfDB *db, PgfRevision revision);
|
||||||
|
|
||||||
|
PGF_API_DECL
|
||||||
|
PgfRevision pgf_checkout_revision(PgfDB *db, PgfExn *err);
|
||||||
|
|
||||||
PGF_API_DECL
|
PGF_API_DECL
|
||||||
void pgf_create_function(PgfDB *db, PgfRevision revision,
|
void pgf_create_function(PgfDB *db, PgfRevision revision,
|
||||||
PgfText *name,
|
PgfText *name,
|
||||||
|
|||||||
@@ -72,24 +72,6 @@ void PgfPhrasetableIds::end()
|
|||||||
pairs = NULL;
|
pairs = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PgfPhrasetableEntry::add_ref()
|
|
||||||
{
|
|
||||||
seq->ref_count++;
|
|
||||||
if (backrefs != 0)
|
|
||||||
backrefs->ref_count++;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PgfPhrasetableEntry::release_ref()
|
|
||||||
{
|
|
||||||
if (!(--seq->ref_count)) {
|
|
||||||
PgfSequence::release(seq);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (backrefs != 0 && !(--backrefs->ref_count)) {
|
|
||||||
PgfSequenceBackrefs::release(backrefs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static
|
static
|
||||||
int lparam_cmp(PgfLParam *p1, PgfLParam *p2)
|
int lparam_cmp(PgfLParam *p1, PgfLParam *p2)
|
||||||
{
|
{
|
||||||
@@ -247,65 +229,57 @@ int sequence_cmp(ref<PgfSequence> seq1, ref<PgfSequence> seq2)
|
|||||||
|
|
||||||
PGF_INTERNAL
|
PGF_INTERNAL
|
||||||
PgfPhrasetable phrasetable_internalize(PgfPhrasetable table,
|
PgfPhrasetable phrasetable_internalize(PgfPhrasetable table,
|
||||||
|
ref<PgfSequence> seq,
|
||||||
object container,
|
object container,
|
||||||
size_t seq_index,
|
size_t seq_index,
|
||||||
ref<PgfSequence> *pseq)
|
ref<PgfPhrasetableEntry> *pentry)
|
||||||
{
|
{
|
||||||
if (table == 0) {
|
if (table == 0) {
|
||||||
PgfPhrasetableEntry entry;
|
PgfPhrasetableEntry entry;
|
||||||
entry.seq = *pseq;
|
entry.seq = seq;
|
||||||
entry.backrefs = PgfDB::malloc<PgfSequenceBackrefs>(sizeof(PgfSequenceBackref));
|
entry.backrefs = vector_new<PgfSequenceBackref>(1);
|
||||||
entry.backrefs->ref_count = 1;
|
entry.backrefs->data[0].container = container;
|
||||||
entry.backrefs->list.len = 1;
|
entry.backrefs->data[0].seq_index = seq_index;
|
||||||
entry.backrefs->list.data[0].container = container;
|
PgfPhrasetable new_table = Node<PgfPhrasetableEntry>::new_node(entry);
|
||||||
entry.backrefs->list.data[0].seq_index = seq_index;
|
*pentry = ref<PgfPhrasetableEntry>::from_ptr(&new_table->value);
|
||||||
entry.seq->ref_count++;
|
return new_table;
|
||||||
return Node<PgfPhrasetableEntry>::new_node(entry);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int cmp = sequence_cmp(*pseq,table->value.seq);
|
int cmp = sequence_cmp(seq,table->value.seq);
|
||||||
if (cmp < 0) {
|
if (cmp < 0) {
|
||||||
PgfPhrasetable left = phrasetable_internalize(table->left,
|
PgfPhrasetable left = phrasetable_internalize(table->left,
|
||||||
|
seq,
|
||||||
container,
|
container,
|
||||||
seq_index,
|
seq_index,
|
||||||
pseq);
|
pentry);
|
||||||
PgfPhrasetable node = Node<PgfPhrasetableEntry>::balanceL(table->value,left,table->right);
|
table = Node<PgfPhrasetableEntry>::upd_node(table,left,table->right);
|
||||||
phrasetable_release(left);
|
return Node<PgfPhrasetableEntry>::balanceL(table);
|
||||||
return node;
|
|
||||||
} else if (cmp > 0) {
|
} else if (cmp > 0) {
|
||||||
PgfPhrasetable right = phrasetable_internalize(table->right,
|
PgfPhrasetable right = phrasetable_internalize(table->right,
|
||||||
|
seq,
|
||||||
container,
|
container,
|
||||||
seq_index,
|
seq_index,
|
||||||
pseq);
|
pentry);
|
||||||
PgfPhrasetable node = Node<PgfPhrasetableEntry>::balanceR(table->value, table->left, right);
|
table = Node<PgfPhrasetableEntry>::upd_node(table, table->left, right);
|
||||||
phrasetable_release(right);
|
return Node<PgfPhrasetableEntry>::balanceR(table);
|
||||||
return node;
|
|
||||||
} else {
|
} else {
|
||||||
if (!(--(*pseq)->ref_count)) {
|
PgfSequence::release(seq);
|
||||||
PgfSequence::release(*pseq);
|
|
||||||
}
|
|
||||||
|
|
||||||
table->value.seq->ref_count++;
|
|
||||||
*pseq = table->value.seq;
|
|
||||||
|
|
||||||
if (table->left != 0)
|
|
||||||
table->left->ref_count++;
|
|
||||||
if (table->right != 0)
|
|
||||||
table->right->ref_count++;
|
|
||||||
|
|
||||||
size_t len = (table->value.backrefs)
|
size_t len = (table->value.backrefs)
|
||||||
? table->value.backrefs->list.len
|
? table->value.backrefs->len
|
||||||
: 0;
|
: 0;
|
||||||
PgfPhrasetableEntry entry;
|
|
||||||
entry.seq = table->value.seq;
|
ref<Vector<PgfSequenceBackref>> backrefs =
|
||||||
entry.backrefs = PgfDB::malloc<PgfSequenceBackrefs>((len+1)*sizeof(PgfSequenceBackref));
|
vector_copy<PgfSequenceBackref>(table->value.backrefs, len+1);
|
||||||
entry.backrefs->ref_count = 1;
|
backrefs->data[len].container = container;
|
||||||
entry.backrefs->list.len = len+1;
|
backrefs->data[len].seq_index = seq_index;
|
||||||
memcpy(entry.backrefs->list.data, table->value.backrefs->list.data, len*sizeof(PgfSequenceBackref));
|
|
||||||
entry.backrefs->list.data[len].container = container;
|
PgfPhrasetable new_table =
|
||||||
entry.backrefs->list.data[len].seq_index = seq_index;
|
Node<PgfPhrasetableEntry>::upd_node(table, table->left, table->right);
|
||||||
entry.seq->ref_count++;
|
Vector<PgfSequenceBackref>::release(new_table->value.backrefs);
|
||||||
return Node<PgfPhrasetableEntry>::new_node(entry,table->left,table->right);
|
new_table->value.backrefs = backrefs;
|
||||||
|
*pentry = ref<PgfPhrasetableEntry>::from_ptr(&new_table->value);
|
||||||
|
return new_table;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -322,13 +296,12 @@ ref<PgfSequence> phrasetable_relink(PgfPhrasetable table,
|
|||||||
else if (seq_id == left_sz) {
|
else if (seq_id == left_sz) {
|
||||||
size_t len = (table->value.backrefs == 0)
|
size_t len = (table->value.backrefs == 0)
|
||||||
? 0
|
? 0
|
||||||
: table->value.backrefs->list.len;
|
: table->value.backrefs->len;
|
||||||
|
|
||||||
ref<PgfSequenceBackrefs> backrefs =
|
ref<Vector<PgfSequenceBackref>> backrefs =
|
||||||
vector_resize<PgfSequenceBackrefs,PgfSequenceBackref>(table->value.backrefs, &PgfSequenceBackrefs::list, len+1);
|
vector_unsafe_resize<PgfSequenceBackref>(table->value.backrefs, len+1);
|
||||||
backrefs->ref_count = 1;
|
backrefs->data[len].container = container;
|
||||||
backrefs->list.data[len].container = container;
|
backrefs->data[len].seq_index = seq_index;
|
||||||
backrefs->list.data[len].seq_index = seq_index;
|
|
||||||
table->value.backrefs = backrefs;
|
table->value.backrefs = backrefs;
|
||||||
|
|
||||||
return table->value.seq;
|
return table->value.seq;
|
||||||
@@ -355,68 +328,66 @@ PgfPhrasetable phrasetable_delete(PgfPhrasetable table,
|
|||||||
seq);
|
seq);
|
||||||
if (left == table->left)
|
if (left == table->left)
|
||||||
return table;
|
return table;
|
||||||
PgfPhrasetable node = Node<PgfPhrasetableEntry>::balanceR(table->value,left,table->right);
|
table = Node<PgfPhrasetableEntry>::upd_node(table,left,table->right);
|
||||||
phrasetable_release(left);
|
return Node<PgfPhrasetableEntry>::balanceR(table);
|
||||||
return node;
|
|
||||||
} else if (cmp > 0) {
|
} else if (cmp > 0) {
|
||||||
PgfPhrasetable right = phrasetable_delete(table->right,
|
PgfPhrasetable right = phrasetable_delete(table->right,
|
||||||
container, seq_index,
|
container, seq_index,
|
||||||
seq);
|
seq);
|
||||||
if (right == table->right)
|
if (right == table->right)
|
||||||
return table;
|
return table;
|
||||||
PgfPhrasetable node = Node<PgfPhrasetableEntry>::balanceL(table->value,table->left,right);
|
table = Node<PgfPhrasetableEntry>::upd_node(table,table->left,right);
|
||||||
phrasetable_release(right);
|
return Node<PgfPhrasetableEntry>::balanceL(table);
|
||||||
return node;
|
|
||||||
} else {
|
} else {
|
||||||
PgfPhrasetableEntry entry;
|
size_t len = table->value.backrefs->len;
|
||||||
|
|
||||||
size_t len = table->value.backrefs->list.len;
|
|
||||||
if (len > 1) {
|
if (len > 1) {
|
||||||
entry.backrefs =
|
ref<Vector<PgfSequenceBackref>> backrefs =
|
||||||
PgfDB::malloc<PgfSequenceBackrefs>((len-1)*sizeof(PgfSequenceBackref));
|
vector_new<PgfSequenceBackref>(len-1);
|
||||||
entry.backrefs->ref_count = 1;
|
|
||||||
entry.backrefs->list.len = len-1;
|
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
while (i < len) {
|
while (i < len) {
|
||||||
PgfSequenceBackref *backref =
|
ref<PgfSequenceBackref> backref =
|
||||||
vector_elem(&table->value.backrefs->list, i);
|
vector_elem(table->value.backrefs, i);
|
||||||
if (backref->container == container &&
|
if (backref->container == container &&
|
||||||
backref->seq_index == seq_index) {
|
backref->seq_index == seq_index) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
*vector_elem(&entry.backrefs->list, i) = *backref;
|
*vector_elem(backrefs, i) = *backref;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
while (i < len) {
|
while (i < len) {
|
||||||
PgfSequenceBackref *backref =
|
ref<PgfSequenceBackref> backref =
|
||||||
vector_elem(&table->value.backrefs->list, i);
|
vector_elem(table->value.backrefs, i);
|
||||||
*vector_elem(&entry.backrefs->list, i-1) = *backref;
|
*vector_elem(backrefs, i-1) = *backref;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
entry.seq = table->value.seq;
|
PgfPhrasetable new_table =
|
||||||
table->value.seq->ref_count++;
|
Node<PgfPhrasetableEntry>::upd_node(table, table->left, table->right);
|
||||||
return Node<PgfPhrasetableEntry>::new_node(entry, table->left, table->right);
|
Vector<PgfSequenceBackref>::release(new_table->value.backrefs);
|
||||||
|
new_table->value.backrefs = backrefs;
|
||||||
|
return new_table;
|
||||||
} else {
|
} else {
|
||||||
|
PgfSequence::release(table->value.seq);
|
||||||
|
Vector<PgfSequenceBackref>::release(table->value.backrefs);
|
||||||
if (table->left == 0) {
|
if (table->left == 0) {
|
||||||
if (table->right != 0)
|
Node<PgfPhrasetableEntry>::release(table);
|
||||||
table->right->ref_count++;
|
|
||||||
return table->right;
|
return table->right;
|
||||||
} else if (table->right == 0) {
|
} else if (table->right == 0) {
|
||||||
if (table->left != 0)
|
Node<PgfPhrasetableEntry>::release(table);
|
||||||
table->left->ref_count++;
|
|
||||||
return table->left;
|
return table->left;
|
||||||
} else if (table->left->sz > table->right->sz) {
|
} else if (table->left->sz > table->right->sz) {
|
||||||
PgfPhrasetable new_left = Node<PgfPhrasetableEntry>::pop_last(table->left, &entry);
|
PgfPhrasetable node;
|
||||||
PgfPhrasetable node = Node<PgfPhrasetableEntry>::balanceR(entry, new_left, table->right);
|
PgfPhrasetable left = Node<PgfPhrasetableEntry>::pop_last(table->left, &node);
|
||||||
phrasetable_release(new_left);
|
node = Node<PgfPhrasetableEntry>::upd_node(node, left, table->right);
|
||||||
return node;
|
Node<PgfPhrasetableEntry>::release(table);
|
||||||
|
return Node<PgfPhrasetableEntry>::balanceR(node);
|
||||||
} else {
|
} else {
|
||||||
PgfPhrasetable new_right = Node<PgfPhrasetableEntry>::pop_first(table->right, &entry);
|
PgfPhrasetable node;
|
||||||
PgfPhrasetable node = Node<PgfPhrasetableEntry>::balanceL(entry, table->left, new_right);
|
PgfPhrasetable right = Node<PgfPhrasetableEntry>::pop_first(table->right, &node);
|
||||||
phrasetable_release(new_right);
|
node = Node<PgfPhrasetableEntry>::upd_node(node, table->left, right);
|
||||||
return node;
|
Node<PgfPhrasetableEntry>::release(table);
|
||||||
|
return Node<PgfPhrasetableEntry>::balanceL(node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -448,8 +419,8 @@ void phrasetable_iter(PgfConcr *concr,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (table->value.backrefs != 0 && res == 0 && callback != 0) {
|
if (table->value.backrefs != 0 && res == 0 && callback != 0) {
|
||||||
for (size_t i = 0; i < table->value.backrefs->list.len; i++) {
|
for (size_t i = 0; i < table->value.backrefs->len; i++) {
|
||||||
PgfSequenceBackref backref = *vector_elem(&table->value.backrefs->list,i);
|
PgfSequenceBackref backref = *vector_elem<PgfSequenceBackref>(table->value.backrefs,i);
|
||||||
switch (ref<PgfConcrLin>::get_tag(backref.container)) {
|
switch (ref<PgfConcrLin>::get_tag(backref.container)) {
|
||||||
case PgfConcrLin::tag: {
|
case PgfConcrLin::tag: {
|
||||||
ref<PgfConcrLin> lin = ref<PgfConcrLin>::untagged(backref.container);
|
ref<PgfConcrLin> lin = ref<PgfConcrLin>::untagged(backref.container);
|
||||||
@@ -481,5 +452,9 @@ void phrasetable_iter(PgfConcr *concr,
|
|||||||
PGF_INTERNAL
|
PGF_INTERNAL
|
||||||
void phrasetable_release(PgfPhrasetable table)
|
void phrasetable_release(PgfPhrasetable table)
|
||||||
{
|
{
|
||||||
|
if (table == 0)
|
||||||
|
return;
|
||||||
|
phrasetable_release(table->left);
|
||||||
|
phrasetable_release(table->right);
|
||||||
Node<PgfPhrasetableEntry>::release(table);
|
Node<PgfPhrasetableEntry>::release(table);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,14 +2,11 @@
|
|||||||
#define PHRASETABLE_H
|
#define PHRASETABLE_H
|
||||||
|
|
||||||
struct PgfSequence;
|
struct PgfSequence;
|
||||||
struct PgfSequenceBackrefs;
|
struct PgfSequenceBackref;
|
||||||
|
|
||||||
struct PGF_INTERNAL_DECL PgfPhrasetableEntry {
|
struct PGF_INTERNAL_DECL PgfPhrasetableEntry {
|
||||||
ref<PgfSequence> seq;
|
ref<PgfSequence> seq;
|
||||||
ref<PgfSequenceBackrefs> backrefs;
|
ref<Vector<PgfSequenceBackref>> backrefs;
|
||||||
|
|
||||||
void add_ref();
|
|
||||||
void release_ref();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class PgfSequenceItor;
|
class PgfSequenceItor;
|
||||||
@@ -52,9 +49,10 @@ private:
|
|||||||
|
|
||||||
PGF_INTERNAL_DECL
|
PGF_INTERNAL_DECL
|
||||||
PgfPhrasetable phrasetable_internalize(PgfPhrasetable table,
|
PgfPhrasetable phrasetable_internalize(PgfPhrasetable table,
|
||||||
|
ref<PgfSequence> seq,
|
||||||
object container,
|
object container,
|
||||||
size_t seq_index,
|
size_t seq_index,
|
||||||
ref<PgfSequence> *seq);
|
ref<PgfPhrasetableEntry> *pentry);
|
||||||
|
|
||||||
PGF_INTERNAL_DECL
|
PGF_INTERNAL_DECL
|
||||||
ref<PgfSequence> phrasetable_relink(PgfPhrasetable table,
|
ref<PgfSequence> phrasetable_relink(PgfPhrasetable table,
|
||||||
|
|||||||
@@ -115,7 +115,11 @@ Namespace<V> PgfReader::read_namespace(ref<V> (PgfReader::*read_value)(), size_t
|
|||||||
ref<V> value = (this->*read_value)();
|
ref<V> value = (this->*read_value)();
|
||||||
Namespace<V> right = read_namespace(read_value, len-half-1);
|
Namespace<V> right = read_namespace(read_value, len-half-1);
|
||||||
|
|
||||||
return Node<ref<V>>::new_node(value, left, right);
|
Namespace<V> node = Node<ref<V>>::new_node(value);
|
||||||
|
node->sz = 1+Node<ref<V>>::size(left)+Node<ref<V>>::size(right);
|
||||||
|
node->left = left;
|
||||||
|
node->right = right;
|
||||||
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class V>
|
template<class V>
|
||||||
@@ -166,7 +170,7 @@ PgfLiteral PgfReader::read_literal()
|
|||||||
case PgfLiteralStr::tag: {
|
case PgfLiteralStr::tag: {
|
||||||
ref<PgfLiteralStr> lit_str =
|
ref<PgfLiteralStr> lit_str =
|
||||||
read_text<PgfLiteralStr>(&PgfLiteralStr::val);
|
read_text<PgfLiteralStr>(&PgfLiteralStr::val);
|
||||||
lit = ref<PgfLiteralStr>::tagged(lit_str);
|
lit = lit_str.tagged();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PgfLiteralInt::tag: {
|
case PgfLiteralInt::tag: {
|
||||||
@@ -177,14 +181,14 @@ PgfLiteral PgfReader::read_literal()
|
|||||||
for (size_t i = 0; i < size; i++) {
|
for (size_t i = 0; i < size; i++) {
|
||||||
lit_int->val[i] = (uintmax_t) read_uint();
|
lit_int->val[i] = (uintmax_t) read_uint();
|
||||||
}
|
}
|
||||||
lit = ref<PgfLiteralInt>::tagged(lit_int);
|
lit = lit_int.tagged();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PgfLiteralFlt::tag: {
|
case PgfLiteralFlt::tag: {
|
||||||
ref<PgfLiteralFlt> lit_flt =
|
ref<PgfLiteralFlt> lit_flt =
|
||||||
current_db->malloc<PgfLiteralFlt>();
|
current_db->malloc<PgfLiteralFlt>();
|
||||||
lit_flt->val = read_double();
|
lit_flt->val = read_double();
|
||||||
lit = ref<PgfLiteralFlt>::tagged(lit_flt);
|
lit = lit_flt.tagged();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@@ -196,7 +200,6 @@ PgfLiteral PgfReader::read_literal()
|
|||||||
ref<PgfFlag> PgfReader::read_flag()
|
ref<PgfFlag> PgfReader::read_flag()
|
||||||
{
|
{
|
||||||
ref<PgfFlag> flag = read_name(&PgfFlag::name);
|
ref<PgfFlag> flag = read_name(&PgfFlag::name);
|
||||||
flag->ref_count = 1;
|
|
||||||
flag->value = read_literal();
|
flag->value = read_literal();
|
||||||
return flag;
|
return flag;
|
||||||
}
|
}
|
||||||
@@ -213,7 +216,7 @@ PgfExpr PgfReader::read_expr()
|
|||||||
eabs->bind_type = bind_type;
|
eabs->bind_type = bind_type;
|
||||||
PgfExpr body = read_expr();
|
PgfExpr body = read_expr();
|
||||||
eabs->body = body;
|
eabs->body = body;
|
||||||
expr = ref<PgfExprAbs>::tagged(eabs);
|
expr = eabs.tagged();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PgfExprApp::tag: {
|
case PgfExprApp::tag: {
|
||||||
@@ -222,31 +225,31 @@ PgfExpr PgfReader::read_expr()
|
|||||||
ref<PgfExprApp> eapp = PgfDB::malloc<PgfExprApp>();
|
ref<PgfExprApp> eapp = PgfDB::malloc<PgfExprApp>();
|
||||||
eapp->fun = fun;
|
eapp->fun = fun;
|
||||||
eapp->arg = arg;
|
eapp->arg = arg;
|
||||||
expr = ref<PgfExprApp>::tagged(eapp);
|
expr = eapp.tagged();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PgfExprLit::tag: {
|
case PgfExprLit::tag: {
|
||||||
PgfExpr lit = read_literal();
|
PgfExpr lit = read_literal();
|
||||||
ref<PgfExprLit> elit = PgfDB::malloc<PgfExprLit>();
|
ref<PgfExprLit> elit = PgfDB::malloc<PgfExprLit>();
|
||||||
elit->lit = lit;
|
elit->lit = lit;
|
||||||
expr = ref<PgfExprLit>::tagged(elit);
|
expr = elit.tagged();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PgfExprMeta::tag: {
|
case PgfExprMeta::tag: {
|
||||||
ref<PgfExprMeta> emeta = PgfDB::malloc<PgfExprMeta>();
|
ref<PgfExprMeta> emeta = PgfDB::malloc<PgfExprMeta>();
|
||||||
emeta->id = read_int();
|
emeta->id = read_int();
|
||||||
expr = ref<PgfExprMeta>::tagged(emeta);
|
expr = emeta.tagged();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PgfExprFun::tag: {
|
case PgfExprFun::tag: {
|
||||||
ref<PgfExprFun> efun = read_name(&PgfExprFun::name);
|
ref<PgfExprFun> efun = read_name(&PgfExprFun::name);
|
||||||
expr = ref<PgfExprFun>::tagged(efun);
|
expr = efun.tagged();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PgfExprVar::tag: {
|
case PgfExprVar::tag: {
|
||||||
ref<PgfExprVar> evar = PgfDB::malloc<PgfExprVar>();
|
ref<PgfExprVar> evar = PgfDB::malloc<PgfExprVar>();
|
||||||
evar->var = read_int();
|
evar->var = read_int();
|
||||||
expr = ref<PgfExprVar>::tagged(evar);
|
expr = evar.tagged();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PgfExprTyped::tag: {
|
case PgfExprTyped::tag: {
|
||||||
@@ -255,14 +258,14 @@ PgfExpr PgfReader::read_expr()
|
|||||||
ref<PgfExprTyped> etyped = PgfDB::malloc<PgfExprTyped>();
|
ref<PgfExprTyped> etyped = PgfDB::malloc<PgfExprTyped>();
|
||||||
etyped->expr = expr;
|
etyped->expr = expr;
|
||||||
etyped->type = type;
|
etyped->type = type;
|
||||||
expr = ref<PgfExprTyped>::tagged(etyped);
|
expr = etyped.tagged();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PgfExprImplArg::tag: {
|
case PgfExprImplArg::tag: {
|
||||||
auto expr = read_expr();
|
auto expr = read_expr();
|
||||||
ref<PgfExprImplArg> eimpl = current_db->malloc<PgfExprImplArg>();
|
ref<PgfExprImplArg> eimpl = current_db->malloc<PgfExprImplArg>();
|
||||||
eimpl->expr = expr;
|
eimpl->expr = expr;
|
||||||
expr = ref<PgfExprImplArg>::tagged(eimpl);
|
expr = eimpl.tagged();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@@ -297,7 +300,6 @@ ref<PgfAbsFun> PgfReader::read_absfun()
|
|||||||
{
|
{
|
||||||
ref<PgfAbsFun> absfun =
|
ref<PgfAbsFun> absfun =
|
||||||
read_name<PgfAbsFun>(&PgfAbsFun::name);
|
read_name<PgfAbsFun>(&PgfAbsFun::name);
|
||||||
absfun->ref_count = 1;
|
|
||||||
ref<PgfExprFun> efun =
|
ref<PgfExprFun> efun =
|
||||||
ref<PgfExprFun>::from_ptr((PgfExprFun*) &absfun->name);
|
ref<PgfExprFun>::from_ptr((PgfExprFun*) &absfun->name);
|
||||||
absfun->type = read_type();
|
absfun->type = read_type();
|
||||||
@@ -323,7 +325,6 @@ ref<PgfAbsFun> PgfReader::read_absfun()
|
|||||||
ref<PgfAbsCat> PgfReader::read_abscat()
|
ref<PgfAbsCat> PgfReader::read_abscat()
|
||||||
{
|
{
|
||||||
ref<PgfAbsCat> abscat = read_name<PgfAbsCat>(&PgfAbsCat::name);
|
ref<PgfAbsCat> abscat = read_name<PgfAbsCat>(&PgfAbsCat::name);
|
||||||
abscat->ref_count = 1;
|
|
||||||
abscat->context = read_vector<PgfHypo>(&PgfReader::read_hypo);
|
abscat->context = read_vector<PgfHypo>(&PgfReader::read_hypo);
|
||||||
abscat->prob = - log(read_double());
|
abscat->prob = - log(read_double());
|
||||||
return abscat;
|
return abscat;
|
||||||
@@ -345,7 +346,7 @@ void PgfReader::merge_abstract(ref<PgfAbstr> abstract)
|
|||||||
|
|
||||||
ref<PgfText> name = read_name();
|
ref<PgfText> name = read_name();
|
||||||
int cmp = textcmp(&(*abstract->name), &(*name));
|
int cmp = textcmp(&(*abstract->name), &(*name));
|
||||||
PgfDB::free(name);
|
text_db_release(name);
|
||||||
if (cmp != 0)
|
if (cmp != 0)
|
||||||
throw pgf_error("The abstract syntax names doesn't match");
|
throw pgf_error("The abstract syntax names doesn't match");
|
||||||
|
|
||||||
@@ -437,24 +438,24 @@ PgfSymbol PgfReader::read_symbol()
|
|||||||
switch (tag) {
|
switch (tag) {
|
||||||
case PgfSymbolCat::tag: {
|
case PgfSymbolCat::tag: {
|
||||||
ref<PgfSymbolCat> sym_cat = read_symbol_idx<PgfSymbolCat>();
|
ref<PgfSymbolCat> sym_cat = read_symbol_idx<PgfSymbolCat>();
|
||||||
sym = ref<PgfSymbolCat>::tagged(sym_cat);
|
sym = sym_cat.tagged();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PgfSymbolLit::tag: {
|
case PgfSymbolLit::tag: {
|
||||||
ref<PgfSymbolLit> sym_lit = read_symbol_idx<PgfSymbolLit>();
|
ref<PgfSymbolLit> sym_lit = read_symbol_idx<PgfSymbolLit>();
|
||||||
sym = ref<PgfSymbolLit>::tagged(sym_lit);
|
sym = sym_lit.tagged();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PgfSymbolVar::tag: {
|
case PgfSymbolVar::tag: {
|
||||||
ref<PgfSymbolVar> sym_var = PgfDB::malloc<PgfSymbolVar>();
|
ref<PgfSymbolVar> sym_var = PgfDB::malloc<PgfSymbolVar>();
|
||||||
sym_var->d = read_int();
|
sym_var->d = read_int();
|
||||||
sym_var->r = read_int();
|
sym_var->r = read_int();
|
||||||
sym = ref<PgfSymbolVar>::tagged(sym_var);
|
sym = sym_var.tagged();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PgfSymbolKS::tag: {
|
case PgfSymbolKS::tag: {
|
||||||
ref<PgfSymbolKS> sym_ks = read_text(&PgfSymbolKS::token);
|
ref<PgfSymbolKS> sym_ks = read_text(&PgfSymbolKS::token);
|
||||||
sym = ref<PgfSymbolKS>::tagged(sym_ks);
|
sym = sym_ks.tagged();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PgfSymbolKP::tag: {
|
case PgfSymbolKP::tag: {
|
||||||
@@ -473,31 +474,31 @@ PgfSymbol PgfReader::read_symbol()
|
|||||||
auto default_form = read_seq();
|
auto default_form = read_seq();
|
||||||
sym_kp->default_form = default_form;
|
sym_kp->default_form = default_form;
|
||||||
|
|
||||||
sym = ref<PgfSymbolKP>::tagged(sym_kp);
|
sym = sym_kp.tagged();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PgfSymbolBIND::tag: {
|
case PgfSymbolBIND::tag: {
|
||||||
sym = ref<PgfSymbolBIND>::tagged(0);
|
sym = ref<PgfSymbolBIND>(0).tagged();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PgfSymbolSOFTBIND::tag: {
|
case PgfSymbolSOFTBIND::tag: {
|
||||||
sym = ref<PgfSymbolSOFTBIND>::tagged(0);
|
sym = ref<PgfSymbolSOFTBIND>(0).tagged();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PgfSymbolNE::tag: {
|
case PgfSymbolNE::tag: {
|
||||||
sym = ref<PgfSymbolNE>::tagged(0);
|
sym = ref<PgfSymbolNE>(0).tagged();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PgfSymbolSOFTSPACE::tag: {
|
case PgfSymbolSOFTSPACE::tag: {
|
||||||
sym = ref<PgfSymbolSOFTSPACE>::tagged(0);
|
sym = ref<PgfSymbolSOFTSPACE>(0).tagged();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PgfSymbolCAPIT::tag: {
|
case PgfSymbolCAPIT::tag: {
|
||||||
sym = ref<PgfSymbolCAPIT>::tagged(0);
|
sym = ref<PgfSymbolCAPIT>(0).tagged();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PgfSymbolALLCAPIT::tag: {
|
case PgfSymbolALLCAPIT::tag: {
|
||||||
sym = ref<PgfSymbolALLCAPIT>::tagged(0);
|
sym = ref<PgfSymbolALLCAPIT>(0).tagged();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@@ -512,7 +513,6 @@ ref<PgfSequence> PgfReader::read_seq()
|
|||||||
size_t n_syms = read_len();
|
size_t n_syms = read_len();
|
||||||
|
|
||||||
ref<PgfSequence> seq = PgfDB::malloc<PgfSequence>(n_syms*sizeof(PgfSymbol));
|
ref<PgfSequence> seq = PgfDB::malloc<PgfSequence>(n_syms*sizeof(PgfSymbol));
|
||||||
seq->ref_count = 1;
|
|
||||||
seq->syms.len = n_syms;
|
seq->syms.len = n_syms;
|
||||||
|
|
||||||
for (size_t i = 0; i < n_syms; i++) {
|
for (size_t i = 0; i < n_syms; i++) {
|
||||||
@@ -553,7 +553,11 @@ PgfPhrasetable PgfReader::read_phrasetable(size_t len)
|
|||||||
value.backrefs = 0;
|
value.backrefs = 0;
|
||||||
PgfPhrasetable right = read_phrasetable(len-half-1);
|
PgfPhrasetable right = read_phrasetable(len-half-1);
|
||||||
|
|
||||||
return Node<PgfPhrasetableEntry>::new_node(value, left, right);
|
PgfPhrasetable table = Node<PgfPhrasetableEntry>::new_node(value);
|
||||||
|
table->sz = 1+Node<PgfPhrasetableEntry>::size(left)+Node<PgfPhrasetableEntry>::size(right);
|
||||||
|
table->left = left;
|
||||||
|
table->right = right;
|
||||||
|
return table;
|
||||||
}
|
}
|
||||||
|
|
||||||
PgfPhrasetable PgfReader::read_phrasetable()
|
PgfPhrasetable PgfReader::read_phrasetable()
|
||||||
@@ -565,31 +569,28 @@ PgfPhrasetable PgfReader::read_phrasetable()
|
|||||||
ref<PgfConcrLincat> PgfReader::read_lincat()
|
ref<PgfConcrLincat> PgfReader::read_lincat()
|
||||||
{
|
{
|
||||||
ref<PgfConcrLincat> lincat = read_name(&PgfConcrLincat::name);
|
ref<PgfConcrLincat> lincat = read_name(&PgfConcrLincat::name);
|
||||||
lincat->ref_count = 1;
|
|
||||||
lincat->abscat = namespace_lookup(abstract->cats, &lincat->name);
|
lincat->abscat = namespace_lookup(abstract->cats, &lincat->name);
|
||||||
lincat->fields = read_vector(&PgfReader::read_text2);
|
lincat->fields = read_vector(&PgfReader::read_text2);
|
||||||
lincat->n_lindefs = read_len();
|
lincat->n_lindefs = read_len();
|
||||||
lincat->args = read_vector(&PgfReader::read_parg);
|
lincat->args = read_vector(&PgfReader::read_parg);
|
||||||
lincat->res = read_vector(&PgfReader::read_presult2);
|
lincat->res = read_vector(&PgfReader::read_presult2);
|
||||||
lincat->seqs = read_seq_ids(ref<PgfConcrLincat>::tagged(lincat));
|
lincat->seqs = read_seq_ids(lincat.tagged());
|
||||||
return lincat;
|
return lincat;
|
||||||
}
|
}
|
||||||
|
|
||||||
ref<PgfConcrLin> PgfReader::read_lin()
|
ref<PgfConcrLin> PgfReader::read_lin()
|
||||||
{
|
{
|
||||||
ref<PgfConcrLin> lin = read_name(&PgfConcrLin::name);
|
ref<PgfConcrLin> lin = read_name(&PgfConcrLin::name);
|
||||||
lin->ref_count = 1;
|
|
||||||
lin->absfun = namespace_lookup(abstract->funs, &lin->name);
|
lin->absfun = namespace_lookup(abstract->funs, &lin->name);
|
||||||
lin->args = read_vector(&PgfReader::read_parg);
|
lin->args = read_vector(&PgfReader::read_parg);
|
||||||
lin->res = read_vector(&PgfReader::read_presult2);
|
lin->res = read_vector(&PgfReader::read_presult2);
|
||||||
lin->seqs = read_seq_ids(ref<PgfConcrLin>::tagged(lin));
|
lin->seqs = read_seq_ids(lin.tagged());
|
||||||
return lin;
|
return lin;
|
||||||
}
|
}
|
||||||
|
|
||||||
ref<PgfConcrPrintname> PgfReader::read_printname()
|
ref<PgfConcrPrintname> PgfReader::read_printname()
|
||||||
{
|
{
|
||||||
ref<PgfConcrPrintname> printname = read_name(&PgfConcrPrintname::name);
|
ref<PgfConcrPrintname> printname = read_name(&PgfConcrPrintname::name);
|
||||||
printname->ref_count = 1;
|
|
||||||
printname->printname = read_text();
|
printname->printname = read_text();
|
||||||
return printname;
|
return printname;
|
||||||
}
|
}
|
||||||
@@ -597,8 +598,6 @@ ref<PgfConcrPrintname> PgfReader::read_printname()
|
|||||||
ref<PgfConcr> PgfReader::read_concrete()
|
ref<PgfConcr> PgfReader::read_concrete()
|
||||||
{
|
{
|
||||||
concrete = read_name(&PgfConcr::name);
|
concrete = read_name(&PgfConcr::name);
|
||||||
concrete->ref_count = 1;
|
|
||||||
concrete->ref_count_ex = 0;
|
|
||||||
concrete->cflags = read_namespace<PgfFlag>(&PgfReader::read_flag);
|
concrete->cflags = read_namespace<PgfFlag>(&PgfReader::read_flag);
|
||||||
concrete->phrasetable = read_phrasetable();
|
concrete->phrasetable = read_phrasetable();
|
||||||
concrete->lincats = read_namespace<PgfConcrLincat>(&PgfReader::read_lincat);
|
concrete->lincats = read_namespace<PgfConcrLincat>(&PgfReader::read_lincat);
|
||||||
@@ -611,9 +610,8 @@ ref<PgfConcr> PgfReader::read_concrete()
|
|||||||
|
|
||||||
ref<PgfPGF> PgfReader::read_pgf()
|
ref<PgfPGF> PgfReader::read_pgf()
|
||||||
{
|
{
|
||||||
ref<PgfPGF> pgf = PgfDB::malloc<PgfPGF>(master_size+1);
|
ref<PgfPGF> pgf = PgfDB::malloc<PgfPGF>();
|
||||||
|
|
||||||
pgf->ref_count = 1;
|
|
||||||
pgf->major_version = read_u16be();
|
pgf->major_version = read_u16be();
|
||||||
pgf->minor_version = read_u16be();
|
pgf->minor_version = read_u16be();
|
||||||
|
|
||||||
@@ -628,12 +626,6 @@ ref<PgfPGF> PgfReader::read_pgf()
|
|||||||
|
|
||||||
pgf->concretes = read_namespace<PgfConcr>(&PgfReader::read_concrete);
|
pgf->concretes = read_namespace<PgfConcr>(&PgfReader::read_concrete);
|
||||||
|
|
||||||
pgf->prev = 0;
|
|
||||||
pgf->next = 0;
|
|
||||||
|
|
||||||
pgf->name.size = master_size;
|
|
||||||
memcpy(&pgf->name.text, master_text, master_size+1);
|
|
||||||
|
|
||||||
return pgf;
|
return pgf;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -654,9 +646,7 @@ void PgfReader::merge_pgf(ref<PgfPGF> pgf)
|
|||||||
size_t len = read_len();
|
size_t len = read_len();
|
||||||
for (size_t i = 0; i < len; i++) {
|
for (size_t i = 0; i < len; i++) {
|
||||||
ref<PgfConcr> concr = PgfReader::read_concrete();
|
ref<PgfConcr> concr = PgfReader::read_concrete();
|
||||||
Namespace<PgfConcr> concrs =
|
pgf->concretes =
|
||||||
namespace_insert(pgf->concretes, concr);
|
namespace_insert(pgf->concretes, concr);
|
||||||
namespace_release(pgf->concretes);
|
|
||||||
pgf->concretes = concrs;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -92,6 +92,12 @@ ref<PgfText> textdup_db(PgfText *t1)
|
|||||||
return t2;
|
return t2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PGF_INTERNAL
|
||||||
|
void text_db_release(ref<PgfText> text)
|
||||||
|
{
|
||||||
|
PgfDB::free(text,text->size+1);
|
||||||
|
}
|
||||||
|
|
||||||
PGF_API uint32_t
|
PGF_API uint32_t
|
||||||
pgf_utf8_decode(const uint8_t **src_inout)
|
pgf_utf8_decode(const uint8_t **src_inout)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -23,6 +23,9 @@ PgfText* textdup(PgfText *t1);
|
|||||||
PGF_INTERNAL_DECL
|
PGF_INTERNAL_DECL
|
||||||
ref<PgfText> textdup_db(PgfText *t1);
|
ref<PgfText> textdup_db(PgfText *t1);
|
||||||
|
|
||||||
|
PGF_INTERNAL
|
||||||
|
void text_db_release(ref<PgfText> text);
|
||||||
|
|
||||||
PGF_API uint32_t
|
PGF_API uint32_t
|
||||||
pgf_utf8_decode(const uint8_t** src_inout);
|
pgf_utf8_decode(const uint8_t** src_inout);
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,11 @@ template <class A>
|
|||||||
struct PGF_INTERNAL Vector {
|
struct PGF_INTERNAL Vector {
|
||||||
size_t len;
|
size_t len;
|
||||||
A data[];
|
A data[];
|
||||||
|
|
||||||
|
public:
|
||||||
|
static void release(ref<Vector> vec) {
|
||||||
|
PgfDB::free(vec, vec->len*sizeof(A));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class A> inline PGF_INTERNAL
|
template <class A> inline PGF_INTERNAL
|
||||||
@@ -18,7 +23,6 @@ ref<Vector<A>> vector_new(size_t len)
|
|||||||
template <class C, class A> inline PGF_INTERNAL
|
template <class C, class A> inline PGF_INTERNAL
|
||||||
ref<C> vector_new(Vector<A> C::* field, size_t len)
|
ref<C> vector_new(Vector<A> C::* field, size_t len)
|
||||||
{
|
{
|
||||||
ptrdiff_t offset = (ptrdiff_t) &(((C*) NULL)->*field);
|
|
||||||
ref<C> res = PgfDB::malloc<C>(len*sizeof(A)).as_object();
|
ref<C> res = PgfDB::malloc<C>(len*sizeof(A)).as_object();
|
||||||
(res->*field).len = len;
|
(res->*field).len = len;
|
||||||
return res;
|
return res;
|
||||||
@@ -27,19 +31,53 @@ ref<C> vector_new(Vector<A> C::* field, size_t len)
|
|||||||
PGF_INTERNAL_DECL size_t
|
PGF_INTERNAL_DECL size_t
|
||||||
get_next_padovan(size_t min);
|
get_next_padovan(size_t min);
|
||||||
|
|
||||||
|
/* Resize a vector by creating a new one and copying the old content.
|
||||||
|
* The new vector is now also safe to update */
|
||||||
template <class A> inline PGF_INTERNAL
|
template <class A> inline PGF_INTERNAL
|
||||||
ref<Vector<A>> vector_resize(ref<Vector<A>> r, size_t len)
|
ref<Vector<A>> vector_copy(ref<Vector<A>> vec, size_t len)
|
||||||
{
|
{
|
||||||
ref<Vector<A>> res = PgfDB::realloc<Vector<A>>(r,get_next_padovan(len)*sizeof(A)).as_object();
|
size_t size = len*sizeof(A);
|
||||||
|
ref<Vector<A>> res = PgfDB::malloc<Vector<A>>(size);
|
||||||
|
res->len = len;
|
||||||
|
memcpy(res->data, vec->data, size);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Resize a vector by changing its length. If there is no enough space
|
||||||
|
* the implementation will create a copy, but whenever possible it will
|
||||||
|
* return the reference of the original vector. In the later case, it
|
||||||
|
* changes the length in-place which means that the function is safe
|
||||||
|
* only if the vector was created during the current transaction. */
|
||||||
|
template <class A> inline PGF_INTERNAL
|
||||||
|
ref<Vector<A>> vector_unsafe_resize(ref<Vector<A>> vec, size_t len)
|
||||||
|
{
|
||||||
|
size_t old_len = get_next_padovan(vec->len);
|
||||||
|
size_t new_len = get_next_padovan(len);
|
||||||
|
|
||||||
|
if (old_len == new_len)
|
||||||
|
return vec;
|
||||||
|
|
||||||
|
ref<Vector<A>> res = PgfDB::realloc<Vector<A>>(vec,old_len*sizeof(A),new_len*sizeof(A)).as_object();
|
||||||
res->len = len;
|
res->len = len;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Resize a vector embedded in another structure, by changing its length.
|
||||||
|
* If there is no enough space the implementation will copy the structure,
|
||||||
|
* but whenever possible it will return a reference to
|
||||||
|
* the original structure. In the later case, it changes
|
||||||
|
* the vector's length in-place which means that the function is safe
|
||||||
|
* only if the structure was created during the current transaction. */
|
||||||
template <class C, class A> inline PGF_INTERNAL
|
template <class C, class A> inline PGF_INTERNAL
|
||||||
ref<C> vector_resize(ref<C> r, Vector<A> C::* field, size_t len)
|
ref<C> vector_unsafe_resize(ref<C> r, Vector<A> C::* field, size_t len)
|
||||||
{
|
{
|
||||||
ptrdiff_t offset = (ptrdiff_t) &(((C*) NULL)->*field);
|
size_t old_len = get_next_padovan((r->*field).len);
|
||||||
ref<C> res = PgfDB::realloc<C>(r,get_next_padovan(len)*sizeof(A)).as_object();
|
size_t new_len = get_next_padovan(len);
|
||||||
|
|
||||||
|
if (old_len == new_len)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
ref<C> res = PgfDB::realloc<C>(r,old_len*sizeof(A),new_len*sizeof(A)).as_object();
|
||||||
(res->*field).len = len;
|
(res->*field).len = len;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -421,7 +421,7 @@ void PgfWriter::write_concrete(ref<PgfConcr> concr)
|
|||||||
void PgfWriter::write_pgf(ref<PgfPGF> pgf)
|
void PgfWriter::write_pgf(ref<PgfPGF> pgf)
|
||||||
{
|
{
|
||||||
write_u16be(pgf->major_version);
|
write_u16be(pgf->major_version);
|
||||||
write_u16be(pgf->minor_version);
|
write_u16be(pgf->minor_version);
|
||||||
|
|
||||||
write_namespace<PgfFlag>(pgf->gflags, &PgfWriter::write_flag);
|
write_namespace<PgfFlag>(pgf->gflags, &PgfWriter::write_flag);
|
||||||
|
|
||||||
|
|||||||
@@ -73,8 +73,6 @@ foreign import ccall pgf_merge_pgf :: Ptr PgfDB -> Ptr PGF -> CString -> Ptr Pgf
|
|||||||
|
|
||||||
foreign import ccall pgf_write_pgf :: CString -> Ptr PgfDB -> Ptr PGF -> Ptr PgfExn -> IO ()
|
foreign import ccall pgf_write_pgf :: CString -> Ptr PgfDB -> Ptr PGF -> Ptr PgfExn -> IO ()
|
||||||
|
|
||||||
foreign import ccall "pgf_free_revision" pgf_free_revision_ :: Ptr PgfDB -> Ptr PGF -> IO ()
|
|
||||||
|
|
||||||
foreign import ccall "&pgf_free_revision" pgf_free_revision :: FinalizerEnvPtr PgfDB PGF
|
foreign import ccall "&pgf_free_revision" pgf_free_revision :: FinalizerEnvPtr PgfDB PGF
|
||||||
|
|
||||||
foreign import ccall "pgf_free_concr_revision" pgf_free_concr_revision_ :: Ptr PgfDB -> Ptr Concr -> IO ()
|
foreign import ccall "pgf_free_concr_revision" pgf_free_concr_revision_ :: Ptr PgfDB -> Ptr Concr -> IO ()
|
||||||
@@ -177,11 +175,13 @@ foreign import ccall pgf_infer_expr :: Ptr PgfDB -> Ptr PGF -> Ptr (StablePtr Ex
|
|||||||
|
|
||||||
foreign import ccall pgf_check_type :: Ptr PgfDB -> Ptr PGF -> Ptr (StablePtr Type) -> Ptr PgfMarshaller -> Ptr PgfUnmarshaller -> Ptr PgfExn -> IO ()
|
foreign import ccall pgf_check_type :: Ptr PgfDB -> Ptr PGF -> Ptr (StablePtr Type) -> Ptr PgfMarshaller -> Ptr PgfUnmarshaller -> Ptr PgfExn -> IO ()
|
||||||
|
|
||||||
foreign import ccall pgf_clone_revision :: Ptr PgfDB -> Ptr PGF -> Ptr PgfText -> Ptr PgfExn -> IO (Ptr PGF)
|
foreign import ccall pgf_start_transaction :: Ptr PgfDB -> Ptr PGF -> Ptr PgfExn -> IO (Ptr PGF)
|
||||||
|
|
||||||
foreign import ccall pgf_commit_revision :: Ptr PgfDB -> Ptr PGF -> Ptr PgfExn -> IO ()
|
foreign import ccall pgf_commit_transaction :: Ptr PgfDB -> Ptr PGF -> Ptr PgfExn -> IO ()
|
||||||
|
|
||||||
foreign import ccall pgf_checkout_revision :: Ptr PgfDB -> Ptr PgfText -> Ptr PgfExn -> IO (Ptr PGF)
|
foreign import ccall pgf_rollback_transaction :: Ptr PgfDB -> Ptr PGF -> IO ()
|
||||||
|
|
||||||
|
foreign import ccall pgf_checkout_revision :: Ptr PgfDB -> Ptr PgfExn -> IO (Ptr PGF)
|
||||||
|
|
||||||
foreign import ccall pgf_create_function :: Ptr PgfDB -> Ptr PGF -> Ptr PgfText -> StablePtr Type -> CSize -> Ptr CChar -> (#type prob_t) -> Ptr PgfMarshaller -> Ptr PgfExn -> IO ()
|
foreign import ccall pgf_create_function :: Ptr PgfDB -> Ptr PGF -> Ptr PgfText -> StablePtr Type -> CSize -> Ptr CChar -> (#type prob_t) -> Ptr PgfMarshaller -> Ptr PgfExn -> IO ()
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ module PGF2.Transactions
|
|||||||
|
|
||||||
-- abstract syntax
|
-- abstract syntax
|
||||||
, modifyPGF
|
, modifyPGF
|
||||||
, branchPGF
|
|
||||||
, checkoutPGF
|
, checkoutPGF
|
||||||
, createFunction
|
, createFunction
|
||||||
, dropFunction
|
, dropFunction
|
||||||
@@ -81,53 +80,39 @@ instance Monad (Transaction k) where
|
|||||||
the new function @foo@.
|
the new function @foo@.
|
||||||
-}
|
-}
|
||||||
modifyPGF :: PGF -> Transaction PGF a -> IO PGF
|
modifyPGF :: PGF -> Transaction PGF a -> IO PGF
|
||||||
modifyPGF = branchPGF_ nullPtr
|
modifyPGF p (Transaction f) =
|
||||||
|
|
||||||
{- | @branchPGF gr branch_name t@ is similar to @modifyPGF gr t@,
|
|
||||||
except that it stores the result as a branch with the given name.
|
|
||||||
-}
|
|
||||||
branchPGF :: PGF -> String -> Transaction PGF a -> IO PGF
|
|
||||||
branchPGF p name t =
|
|
||||||
withText name $ \c_name ->
|
|
||||||
branchPGF_ c_name p t
|
|
||||||
|
|
||||||
branchPGF_ :: Ptr PgfText -> PGF -> Transaction PGF a -> IO PGF
|
|
||||||
branchPGF_ c_name p (Transaction f) =
|
|
||||||
withForeignPtr (a_revision p) $ \c_revision ->
|
withForeignPtr (a_revision p) $ \c_revision ->
|
||||||
withPgfExn "branchPGF" $ \c_exn ->
|
withPgfExn "modifyPGF" $ \c_exn ->
|
||||||
mask $ \restore -> do
|
mask $ \restore -> do
|
||||||
c_revision <- pgf_clone_revision (a_db p) c_revision c_name c_exn
|
c_revision <- pgf_start_transaction (a_db p) c_revision c_exn
|
||||||
ex_type <- (#peek PgfExn, type) c_exn
|
ex_type <- (#peek PgfExn, type) c_exn
|
||||||
if (ex_type :: (#type PgfExnType)) == (#const PGF_EXN_NONE)
|
if (ex_type :: (#type PgfExnType)) == (#const PGF_EXN_NONE)
|
||||||
then do ((restore (f (a_db p) c_revision c_revision c_exn))
|
then do ((restore (f (a_db p) c_revision c_revision c_exn))
|
||||||
`catch`
|
`catch`
|
||||||
(\e -> do
|
(\e -> do
|
||||||
pgf_free_revision_ (a_db p) c_revision
|
pgf_rollback_transaction (a_db p) c_revision
|
||||||
throwIO (e :: SomeException)))
|
throwIO (e :: SomeException)))
|
||||||
ex_type <- (#peek PgfExn, type) c_exn
|
ex_type <- (#peek PgfExn, type) c_exn
|
||||||
if (ex_type :: (#type PgfExnType)) == (#const PGF_EXN_NONE)
|
if (ex_type :: (#type PgfExnType)) == (#const PGF_EXN_NONE)
|
||||||
then do pgf_commit_revision (a_db p) c_revision c_exn
|
then do pgf_commit_transaction (a_db p) c_revision c_exn
|
||||||
ex_type <- (#peek PgfExn, type) c_exn
|
ex_type <- (#peek PgfExn, type) c_exn
|
||||||
if (ex_type :: (#type PgfExnType)) == (#const PGF_EXN_NONE)
|
if (ex_type :: (#type PgfExnType)) == (#const PGF_EXN_NONE)
|
||||||
then do fptr <- newForeignPtrEnv pgf_free_revision (a_db p) c_revision
|
then do fptr <- newForeignPtrEnv pgf_free_revision (a_db p) c_revision
|
||||||
langs <- getConcretes (a_db p) fptr
|
langs <- getConcretes (a_db p) fptr
|
||||||
return (PGF (a_db p) fptr langs)
|
return (PGF (a_db p) fptr langs)
|
||||||
else do pgf_free_revision_ (a_db p) c_revision
|
else do pgf_rollback_transaction (a_db p) c_revision
|
||||||
return p
|
return p
|
||||||
else do pgf_free_revision_ (a_db p) c_revision
|
else do pgf_rollback_transaction (a_db p) c_revision
|
||||||
return p
|
return p
|
||||||
else return p
|
else return p
|
||||||
|
|
||||||
{- | Retrieves the branch with the given name -}
|
{- | Retrieves the branch with the given name -}
|
||||||
checkoutPGF :: PGF -> String -> IO (Maybe PGF)
|
checkoutPGF :: PGF -> IO PGF
|
||||||
checkoutPGF p name =
|
checkoutPGF p = do
|
||||||
withText name $ \c_name -> do
|
c_revision <- withPgfExn "checkoutPGF" (pgf_checkout_revision (a_db p))
|
||||||
c_revision <- withPgfExn "checkoutPGF" (pgf_checkout_revision (a_db p) c_name)
|
fptr <- newForeignPtrEnv pgf_free_revision (a_db p) c_revision
|
||||||
if c_revision == nullPtr
|
langs <- getConcretes (a_db p) fptr
|
||||||
then return Nothing
|
return (PGF (a_db p) fptr langs)
|
||||||
else do fptr <- newForeignPtrEnv pgf_free_revision (a_db p) c_revision
|
|
||||||
langs <- getConcretes (a_db p) fptr
|
|
||||||
return (Just (PGF (a_db p) fptr langs))
|
|
||||||
|
|
||||||
createFunction :: Fun -> Type -> Int -> [[Instr]] -> Float -> Transaction PGF ()
|
createFunction :: Fun -> Type -> Int -> [[Instr]] -> Float -> Transaction PGF ()
|
||||||
createFunction name ty arity bytecode prob = Transaction $ \c_db _ c_revision c_exn ->
|
createFunction name ty arity bytecode prob = Transaction $ \c_db _ c_revision c_exn ->
|
||||||
|
|||||||
@@ -9,13 +9,12 @@ main = do
|
|||||||
gr1 <- readPGF "tests/basic.pgf"
|
gr1 <- readPGF "tests/basic.pgf"
|
||||||
let Just ty = readType "(N -> N) -> P (s z)"
|
let Just ty = readType "(N -> N) -> P (s z)"
|
||||||
|
|
||||||
gr2 <- modifyPGF gr1 (createFunction "foo" ty 0 [] pi >>
|
print 1
|
||||||
createCategory "Q" [(Explicit,"x",ty)] pi)
|
gr2 <- modifyPGF gr1 (createFunction "foo" ty 0 [] pi >>
|
||||||
gr3 <- branchPGF gr1 "bar_branch" (createFunction "bar" ty 0 [] pi >>
|
createCategory "Q" [(Explicit,"x",ty)] pi)
|
||||||
createCategory "R" [(Explicit,"x",ty)] pi)
|
print 2
|
||||||
|
|
||||||
Just gr4 <- checkoutPGF gr1 "master"
|
gr4 <- checkoutPGF gr1
|
||||||
Just gr5 <- checkoutPGF gr1 "bar_branch"
|
|
||||||
|
|
||||||
gr6 <- modifyPGF gr1 (dropFunction "ind" >> dropCategory "S")
|
gr6 <- modifyPGF gr1 (dropFunction "ind" >> dropCategory "S")
|
||||||
|
|
||||||
@@ -28,14 +27,10 @@ main = do
|
|||||||
TestList $
|
TestList $
|
||||||
[TestCase (assertEqual "original functions" ["c","floatLit","ind","intLit","nat","s","stringLit","z"] (functions gr1))
|
[TestCase (assertEqual "original functions" ["c","floatLit","ind","intLit","nat","s","stringLit","z"] (functions gr1))
|
||||||
,TestCase (assertEqual "extended functions" ["c","floatLit","foo","ind","intLit","nat","s","stringLit","z"] (functions gr2))
|
,TestCase (assertEqual "extended functions" ["c","floatLit","foo","ind","intLit","nat","s","stringLit","z"] (functions gr2))
|
||||||
,TestCase (assertEqual "branched functions" ["bar","c","floatLit","ind","intLit","nat","s","stringLit","z"] (functions gr3))
|
|
||||||
,TestCase (assertEqual "checked-out extended functions" ["c","floatLit","foo","ind","intLit","nat","s","stringLit","z"] (functions gr4))
|
,TestCase (assertEqual "checked-out extended functions" ["c","floatLit","foo","ind","intLit","nat","s","stringLit","z"] (functions gr4))
|
||||||
,TestCase (assertEqual "checked-out branched functions" ["bar","c","floatLit","ind","intLit","nat","s","stringLit","z"] (functions gr5))
|
|
||||||
,TestCase (assertEqual "original categories" ["Float","Int","N","P","S","String"] (categories gr1))
|
,TestCase (assertEqual "original categories" ["Float","Int","N","P","S","String"] (categories gr1))
|
||||||
,TestCase (assertEqual "extended categories" ["Float","Int","N","P","Q","S","String"] (categories gr2))
|
,TestCase (assertEqual "extended categories" ["Float","Int","N","P","Q","S","String"] (categories gr2))
|
||||||
,TestCase (assertEqual "branched categories" ["Float","Int","N","P","R","S","String"] (categories gr3))
|
|
||||||
,TestCase (assertEqual "Q context" (Just [(Explicit,"x",ty)]) (categoryContext gr2 "Q"))
|
,TestCase (assertEqual "Q context" (Just [(Explicit,"x",ty)]) (categoryContext gr2 "Q"))
|
||||||
,TestCase (assertEqual "R context" (Just [(Explicit,"x",ty)]) (categoryContext gr3 "R"))
|
|
||||||
,TestCase (assertEqual "reduced functions" ["c","floatLit","intLit","nat","s","stringLit","z"] (functions gr6))
|
,TestCase (assertEqual "reduced functions" ["c","floatLit","intLit","nat","s","stringLit","z"] (functions gr6))
|
||||||
,TestCase (assertEqual "reduced categories" ["Float","Int","N","P","String"] (categories gr6))
|
,TestCase (assertEqual "reduced categories" ["Float","Int","N","P","String"] (categories gr6))
|
||||||
,TestCase (assertEqual "old function type" Nothing (functionType gr1 "foo"))
|
,TestCase (assertEqual "old function type" Nothing (functionType gr1 "foo"))
|
||||||
|
|||||||
@@ -129,7 +129,7 @@ export const runtime = ffi.Library('libpgf', {
|
|||||||
pgf_print_context: [PgfTextPtr, [size_t, PgfTypeHypoPtr, PgfPrintContextPtr, ref.types.int, PgfMarshallerPtr]],
|
pgf_print_context: [PgfTextPtr, [size_t, PgfTypeHypoPtr, PgfPrintContextPtr, ref.types.int, PgfMarshallerPtr]],
|
||||||
pgf_read_type: [PgfType, [PgfTextPtr, PgfUnmarshallerPtr]],
|
pgf_read_type: [PgfType, [PgfTextPtr, PgfUnmarshallerPtr]],
|
||||||
|
|
||||||
pgf_clone_revision: [PgfRevision, [PgfDBPtr, PgfRevision, PgfTextPtr, PgfExnPtr]],
|
pgf_clone_revision: [PgfRevision, [PgfDBPtr, PgfRevision, PgfExnPtr]],
|
||||||
pgf_commit_revision: [ref.types.void, [PgfDBPtr, PgfRevision, PgfExnPtr]],
|
pgf_commit_revision: [ref.types.void, [PgfDBPtr, PgfRevision, PgfExnPtr]],
|
||||||
pgf_checkout_revision: [PgfRevision, [PgfDBPtr, PgfTextPtr, PgfExnPtr]],
|
pgf_checkout_revision: [PgfRevision, [PgfDBPtr, PgfTextPtr, PgfExnPtr]],
|
||||||
pgf_create_function: [ref.types.void, [PgfDBPtr, PgfRevision, PgfTextPtr, PgfType, size_t, prob_t, PgfMarshallerPtr, PgfExnPtr]],
|
pgf_create_function: [ref.types.void, [PgfDBPtr, PgfRevision, PgfTextPtr, PgfType, size_t, prob_t, PgfMarshallerPtr, PgfExnPtr]],
|
||||||
|
|||||||
@@ -27,18 +27,6 @@ def gr3(gr1):
|
|||||||
t.createCategory("R", [(BIND_TYPE_EXPLICIT, "x", ty)], prob)
|
t.createCategory("R", [(BIND_TYPE_EXPLICIT, "x", ty)], prob)
|
||||||
yield gr
|
yield gr
|
||||||
|
|
||||||
@pytest.fixture(scope="function")
|
|
||||||
def gr4(gr2):
|
|
||||||
gr = gr2
|
|
||||||
gr.checkoutBranch("master")
|
|
||||||
yield gr
|
|
||||||
|
|
||||||
@pytest.fixture(scope="function")
|
|
||||||
def gr5(gr3):
|
|
||||||
gr = gr3
|
|
||||||
gr.checkoutBranch("bar_branch")
|
|
||||||
yield gr
|
|
||||||
|
|
||||||
@pytest.fixture(scope="function")
|
@pytest.fixture(scope="function")
|
||||||
def gr6(gr1):
|
def gr6(gr1):
|
||||||
gr = gr1
|
gr = gr1
|
||||||
@@ -47,12 +35,6 @@ def gr6(gr1):
|
|||||||
t.dropCategory("S")
|
t.dropCategory("S")
|
||||||
yield gr
|
yield gr
|
||||||
|
|
||||||
# general
|
|
||||||
|
|
||||||
def test_checkout_non_existant(gr1):
|
|
||||||
with pytest.raises(KeyError):
|
|
||||||
gr1.checkoutBranch("abc")
|
|
||||||
|
|
||||||
# gr1
|
# gr1
|
||||||
|
|
||||||
def test_original_functions(gr1):
|
def test_original_functions(gr1):
|
||||||
@@ -118,14 +100,6 @@ def test_branched_category_context(gr3):
|
|||||||
def test_branched_function_type(gr3):
|
def test_branched_function_type(gr3):
|
||||||
assert gr3.functionType("bar") == ty
|
assert gr3.functionType("bar") == ty
|
||||||
|
|
||||||
# gr4, 5
|
|
||||||
|
|
||||||
def test_branched_functions(gr4):
|
|
||||||
assert gr4.functions == ["c", "foo", "ind", "s", "z"]
|
|
||||||
|
|
||||||
def test_branched_functions(gr5):
|
|
||||||
assert gr5.functions == ["bar", 'c', 'floatLit', 'ind', 'intLit', 'nat', 's', 'stringLit', 'z']
|
|
||||||
|
|
||||||
# gr6
|
# gr6
|
||||||
|
|
||||||
def test_reduced_functions(gr6):
|
def test_reduced_functions(gr6):
|
||||||
|
|||||||
@@ -10,16 +10,12 @@
|
|||||||
PyObject *
|
PyObject *
|
||||||
PGF_checkoutBranch(PGFObject *self, PyObject *args)
|
PGF_checkoutBranch(PGFObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
const char *s = NULL;
|
if (!PyArg_ParseTuple(args, ""))
|
||||||
Py_ssize_t size;
|
|
||||||
if (!PyArg_ParseTuple(args, "s#", &s, &size))
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
PgfText *name = CString_AsPgfText(s, size);
|
|
||||||
|
|
||||||
PgfExn err;
|
PgfExn err;
|
||||||
PgfRevision rev = pgf_checkout_revision(self->db, name, &err);
|
PgfRevision rev = pgf_checkout_revision(self->db, &err);
|
||||||
FreePgfText(name);
|
|
||||||
if (handleError(err) != PGF_EXN_NONE) {
|
if (handleError(err) != PGF_EXN_NONE) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -38,21 +34,13 @@ PGF_checkoutBranch(PGFObject *self, PyObject *args)
|
|||||||
TransactionObject *
|
TransactionObject *
|
||||||
PGF_newTransaction(PGFObject *self, PyObject *args)
|
PGF_newTransaction(PGFObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
PgfText *name = NULL;
|
|
||||||
const char *s = NULL;
|
const char *s = NULL;
|
||||||
Py_ssize_t size;
|
Py_ssize_t size;
|
||||||
if (!PyArg_ParseTuple(args, "|s#", &s, &size))
|
if (!PyArg_ParseTuple(args, "|s#", &s, &size))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (s != NULL) {
|
|
||||||
name = CString_AsPgfText(s, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
PgfExn err;
|
PgfExn err;
|
||||||
PgfRevision rev = pgf_clone_revision(self->db, self->revision, name, &err);
|
PgfRevision rev = pgf_start_transaction(self->db, self->revision, &err);
|
||||||
if (name != NULL) {
|
|
||||||
FreePgfText(name);
|
|
||||||
}
|
|
||||||
if (handleError(err) != PGF_EXN_NONE) {
|
if (handleError(err) != PGF_EXN_NONE) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -123,7 +111,7 @@ static PyObject *
|
|||||||
Transaction_commit(TransactionObject *self, PyObject *args)
|
Transaction_commit(TransactionObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
PgfExn err;
|
PgfExn err;
|
||||||
pgf_commit_revision(self->pgf->db, self->revision, &err);
|
pgf_commit_transaction(self->pgf->db, self->revision, &err);
|
||||||
if (handleError(err) != PGF_EXN_NONE) {
|
if (handleError(err) != PGF_EXN_NONE) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user