Skip to content

Commit

Permalink
concrete revisions not longer take space in the revision registry
Browse files Browse the repository at this point in the history
  • Loading branch information
krangelov committed Sep 21, 2024
1 parent 8878edd commit 43671f3
Show file tree
Hide file tree
Showing 7 changed files with 118 additions and 57 deletions.
4 changes: 2 additions & 2 deletions src/compiler/api/GF/Compile/ExampleBased.hs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ convertFile conf src file = do
(ex, end) = break (=='"') (tail exend)
in ((unwords (words cat),ex), tail end) -- quotes ignored
pgf = resource_pgf conf
lang = language conf
lang = concrete conf
convEx (cat,ex) = do
appn "("
let typ = maybe (error "no valid cat") id $ readType cat
Expand Down Expand Up @@ -61,7 +61,7 @@ convertFile conf src file = do
data ExConfiguration = ExConf {
resource_pgf :: PGF,
verbose :: Bool,
language :: Concr,
concrete :: Concr,
printExp :: Expr -> String
}

Expand Down
4 changes: 0 additions & 4 deletions src/runtime/c/pgf/data.h
Original file line number Diff line number Diff line change
Expand Up @@ -397,8 +397,6 @@ struct PGF_INTERNAL_DECL PgfLRState {
};

struct PGF_INTERNAL_DECL PgfConcr {
static const uint8_t tag = 1;

Namespace<PgfFlag> cflags;
Namespace<PgfConcrLin> lins;
Namespace<PgfConcrLincat> lincats;
Expand All @@ -413,8 +411,6 @@ struct PGF_INTERNAL_DECL PgfConcr {
};

struct PGF_INTERNAL_DECL PgfPGF {
static const uint8_t tag = 0;

uint16_t major_version;
uint16_t minor_version;
Namespace<PgfFlag> gflags;
Expand Down
72 changes: 50 additions & 22 deletions src/runtime/c/pgf/db.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ struct PGF_INTERNAL_DECL malloc_state
object free_descriptors;

size_t n_revisions;
object active_revision;
PgfRevision active_revision;
revision_entry revisions[];
};

Expand Down Expand Up @@ -484,7 +484,7 @@ txn_t PgfDB::get_txn_id() {
}

PGF_INTERNAL
object PgfDB::register_revision(object o, txn_t txn_id)
PgfRevision PgfDB::register_revision(object o, txn_t txn_id)
{
#ifndef _WIN32
pthread_mutex_lock(&ms->rev_mutex);
Expand Down Expand Up @@ -564,7 +564,7 @@ object PgfDB::register_revision(object o, txn_t txn_id)
}

PGF_INTERNAL
void PgfDB::unregister_revision(object revision)
PgfConcrRevision PgfDB::register_concr_revision(PgfRevision revision, size_t index)
{
if (revision == 0 || revision-1 >= ms->n_revisions)
throw pgf_error("Invalid revision");
Expand All @@ -573,6 +573,40 @@ void PgfDB::unregister_revision(object revision)
if (entry->ref_count == 0)
throw pgf_error("Invalid revision");

// The index must be at most 16 bits long
if (((index+1) & ((1 << 16) - 1)) != (index+1))
throw pgf_error("Invalid revision");

#ifndef _WIN32
pthread_mutex_lock(&ms->rev_mutex);
#else
WaitForSingleObject(hRevMutex, INFINITE);
#endif

entry->ref_count++;

#ifndef _WIN32
pthread_mutex_unlock(&ms->rev_mutex);
#else
ReleaseMutex(hRevMutex);
#endif

return revision | ((index+1) << 16);
}

PGF_INTERNAL
void PgfDB::unregister_revision(PgfRevision revision)
{
// Take a way the higher bits for a concrete revision
revision &= ((1 << 16) - 1);

if (revision == 0 || revision-1 >= ms->n_revisions)
throw pgf_error("Invalid revision");

revision_entry *entry = &ms->revisions[revision-1];
if (entry->ref_count == 0)
throw pgf_error("Invalid revision");

#ifndef _WIN32
pthread_mutex_lock(&ms->rev_mutex);
#else
Expand Down Expand Up @@ -700,7 +734,7 @@ void PgfDB::cleanup_state()
}

PGF_INTERNAL
object PgfDB::get_active_revision()
PgfRevision PgfDB::get_active_revision()
{
return current_db->ms->active_revision;
}
Expand Down Expand Up @@ -1457,7 +1491,7 @@ void PgfDB::free_internal(object o, size_t bytes)
}

PGF_INTERNAL
ref<PgfPGF> PgfDB::revision2pgf(PgfRevision revision, size_t *p_txn_id)
ref<PgfPGF> PgfDB::revision2pgf(PgfRevision revision)
{
if (revision == 0 || revision-1 >= ms->n_revisions)
throw pgf_error("Invalid revision");
Expand All @@ -1466,39 +1500,33 @@ ref<PgfPGF> PgfDB::revision2pgf(PgfRevision revision, size_t *p_txn_id)
if (entry->ref_count == 0)
throw pgf_error("Invalid revision");

if (ref<PgfPGF>::get_tag(entry->o) != PgfPGF::tag)
throw pgf_error("Invalid revision");

ref<PgfPGF> pgf = ref<PgfPGF>::untagged(entry->o);
if (pgf.as_object() >= top)
if (entry->o >= top)
throw pgf_error("Invalid revision");

if (p_txn_id != NULL)
*p_txn_id = entry->txn_id;

return pgf;
return entry->o;
}

PGF_INTERNAL
ref<PgfConcr> PgfDB::revision2concr(PgfConcrRevision revision, size_t *p_txn_id)
ref<PgfConcr> PgfDB::revision2concr(PgfConcrRevision concr_revision)
{
PgfRevision revision = concr_revision & ((1 << 16) - 1);
size_t index = concr_revision >> 16;

if (revision == 0 || revision-1 >= ms->n_revisions)
throw pgf_error("Invalid revision");

revision_entry *entry = &ms->revisions[revision-1];
if (entry->ref_count == 0)
throw pgf_error("Invalid revision");

if (ref<PgfPGF>::get_tag(entry->o) != PgfConcr::tag)
ref<PgfPGF> pgf = entry->o;
if (pgf.as_object() >= top)
throw pgf_error("Invalid revision");

ref<PgfConcr> concr = ref<PgfConcr>::untagged(entry->o);
if (concr.as_object() >= top)
ref<PgfConcr> concr = namespace_index(pgf->concretes, index-1);
if (concr == 0)
throw pgf_error("Invalid revision");

if (p_txn_id != NULL)
*p_txn_id = entry->txn_id;

return concr;
}

Expand Down Expand Up @@ -1558,7 +1586,7 @@ void PgfDB::commit(object o)
object save_top = ms->top;
object save_free_blocks = ms->free_blocks;
object save_free_descriptors = ms->free_descriptors;
object save_active_revision = ms->active_revision;
PgfRevision save_active_revision = ms->active_revision;

#ifndef _WIN32
int res;
Expand Down
11 changes: 6 additions & 5 deletions src/runtime/c/pgf/db.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,12 +124,13 @@ class PgfDB {
current_db->free_internal(o.as_object(), sizeof(A)+extra_bytes);
}

PGF_INTERNAL_DECL object get_active_revision();
PGF_INTERNAL_DECL object register_revision(object o, txn_t txn_id);
PGF_INTERNAL_DECL void unregister_revision(object o);
PGF_INTERNAL_DECL PgfRevision get_active_revision();
PGF_INTERNAL_DECL PgfRevision register_revision(object o, txn_t txn_id);
PGF_INTERNAL_DECL PgfConcrRevision register_concr_revision(PgfRevision revision, size_t index);
PGF_INTERNAL_DECL void unregister_revision(PgfRevision o);

PGF_INTERNAL_DECL ref<PgfPGF> revision2pgf(PgfRevision revision, size_t *p_txn_id = NULL);
PGF_INTERNAL_DECL ref<PgfConcr> revision2concr(PgfConcrRevision revision, size_t *p_txn_id = NULL);
PGF_INTERNAL_DECL ref<PgfPGF> revision2pgf(PgfRevision revision);
PGF_INTERNAL_DECL ref<PgfConcr> revision2concr(PgfConcrRevision concr_revision);

PGF_INTERNAL_DECL void start_transaction();
PGF_INTERNAL_DECL void set_transaction_object(object o);
Expand Down
35 changes: 35 additions & 0 deletions src/runtime/c/pgf/namespace.h
Original file line number Diff line number Diff line change
Expand Up @@ -606,6 +606,41 @@ ref<V> namespace_lookup(Namespace<V> map, PgfText *name)
return 0;
}

template <class V>
ref<V> namespace_lookup_index(Namespace<V> map, PgfText *name, size_t *pIndex)
{
*pIndex = 0;
while (map != 0) {
int cmp = textcmp(name,&map->value->name);
if (cmp < 0) {
map = map->left;
} else if (cmp > 0) {
map = map->right;
*pIndex += Node<ref<V>>::size(map->left)+1;
} else {
return map->value;
}
}
return 0;
}

template <class V>
ref<V> namespace_index(Namespace<V> map, size_t index)
{
while (map != 0) {
size_t sz = Node<ref<V>>::size(map->left);
if (index < sz) {
map = map->left;
} else if (index > sz) {
map = map->right;
index -= sz+1;
} else {
return map->value;
}
}
return 0;
}

template <class V>
size_t namespace_size(Namespace<V> map)
{
Expand Down
47 changes: 24 additions & 23 deletions src/runtime/c/pgf/pgf.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ PgfDB *pgf_read_pgf(const char* fpath, PgfRevision *revision,

db->set_transaction_object(pgf.as_object());

*revision = db->register_revision(pgf.tagged(), PgfDB::get_txn_id());
*revision = db->register_revision(pgf.as_object(), PgfDB::get_txn_id());
db->commit(pgf.as_object());
}

Expand Down Expand Up @@ -126,7 +126,7 @@ PgfDB *pgf_boot_ngf(const char* pgf_path, const char* ngf_path,

db->set_transaction_object(pgf.as_object());

*revision = db->register_revision(pgf.tagged(), PgfDB::get_txn_id());
*revision = db->register_revision(pgf.as_object(), PgfDB::get_txn_id());
db->commit(pgf.as_object());
}

Expand Down Expand Up @@ -199,7 +199,7 @@ PgfDB *pgf_boot_ngf_cookie(void *cookie,

db->set_transaction_object(pgf.as_object());

*revision = db->register_revision(pgf.tagged(), PgfDB::get_txn_id());
*revision = db->register_revision(pgf.as_object(), PgfDB::get_txn_id());
db->commit(pgf.as_object());
}

Expand Down Expand Up @@ -234,7 +234,7 @@ PgfDB *pgf_read_ngf(const char *fpath,
ref<PgfPGF> pgf = db->get_active_revision();
*revision = 0;
if (pgf != 0) {
*revision = db->register_revision(pgf.tagged(), PgfDB::get_txn_id()-1);
*revision = db->register_revision(pgf.as_object(), PgfDB::get_txn_id()-1);
db->ref_count++;
}
}
Expand Down Expand Up @@ -284,7 +284,7 @@ PgfDB *pgf_new_ngf(PgfText *abstract_name,

db->set_transaction_object(pgf.as_object());

*revision = db->register_revision(pgf.tagged(), PgfDB::get_txn_id());
*revision = db->register_revision(pgf.as_object(), PgfDB::get_txn_id());
db->commit(pgf.as_object());
}

Expand Down Expand Up @@ -469,14 +469,14 @@ void pgf_iter_concretes(PgfDB *db, PgfRevision revision,
PgfItor *itor, PgfExn *err)
{
PGF_API_BEGIN {
size_t txn_id;

DB_scope scope(db, READER_SCOPE);
ref<PgfPGF> pgf = db->revision2pgf(revision, &txn_id);
ref<PgfPGF> pgf = db->revision2pgf(revision);
size_t index = 0;

std::function<bool(ref<PgfConcr>)> f =
[txn_id,db,itor,err](ref<PgfConcr> concr) {
object rev = db->register_revision(concr.tagged(), txn_id);
[db,revision,itor,err,&index](ref<PgfConcr> concr) {
PgfConcrRevision rev = db->register_concr_revision(revision, index);
index++;
db->ref_count++;
itor->fn(itor, &concr->name, rev, err);
return (err->type == PGF_EXN_NONE);
Expand All @@ -490,18 +490,17 @@ PgfConcrRevision pgf_get_concrete(PgfDB *db, PgfRevision revision,
PgfText *name, PgfExn *err)
{
PGF_API_BEGIN {
size_t txn_id;

DB_scope scope(db, READER_SCOPE);
ref<PgfPGF> pgf = db->revision2pgf(revision, &txn_id);
ref<PgfPGF> pgf = db->revision2pgf(revision);

size_t index;
ref<PgfConcr> concr =
namespace_lookup(pgf->concretes, name);
namespace_lookup_index(pgf->concretes, name, &index);
if (concr == 0)
return 0;

db->ref_count++;
return db->register_revision(concr.tagged(), txn_id);
return db->register_concr_revision(revision, index);
} PGF_API_END

return 0;
Expand Down Expand Up @@ -1425,7 +1424,7 @@ PgfRevision pgf_start_transaction(PgfDB *db, PgfExn *err)

db->set_transaction_object(new_pgf.as_object());

object rev = db->register_revision(new_pgf.tagged(), PgfDB::get_txn_id());
object rev = db->register_revision(new_pgf.as_object(), PgfDB::get_txn_id());

PgfDB::free(pgf);

Expand Down Expand Up @@ -1456,7 +1455,7 @@ PgfRevision pgf_checkout_revision(PgfDB *db, PgfExn *err)
ref<PgfPGF> pgf = db->get_active_revision();
object rev = 0;
if (pgf != 0) {
rev = db->register_revision(pgf.tagged(), PgfDB::get_txn_id()-1);
rev = db->register_revision(pgf.as_object(), PgfDB::get_txn_id()-1);
db->ref_count++;
}
return rev;
Expand Down Expand Up @@ -1689,8 +1688,9 @@ PgfConcrRevision pgf_create_concrete(PgfDB *db, PgfRevision revision,

ref<PgfPGF> pgf = db->revision2pgf(revision);

size_t index;
ref<PgfConcr> concr =
namespace_lookup(pgf->concretes, name);
namespace_lookup_index(pgf->concretes, name, &index);
if (concr != 0)
throw pgf_error("The concrete syntax already exists");

Expand All @@ -1702,15 +1702,15 @@ PgfConcrRevision pgf_create_concrete(PgfDB *db, PgfRevision revision,
concr->printnames = 0;
memcpy(&concr->name, name, sizeof(PgfText)+name->size+1);

object rev = db->register_revision(concr.tagged(), PgfDB::get_txn_id());

Namespace<PgfConcr> concrs =
namespace_insert(pgf->concretes, concr);
if (concrs == 0) {
throw pgf_error("A concrete language with that name already exists");
}
pgf->concretes = concrs;

object rev = db->register_concr_revision(revision, index);

db->ref_count++;
return rev;
} PGF_API_END
Expand All @@ -1726,15 +1726,16 @@ PgfConcrRevision pgf_clone_concrete(PgfDB *db, PgfRevision revision,
DB_scope scope(db, WRITER_SCOPE);

ref<PgfPGF> pgf = db->revision2pgf(revision);


size_t index;
ref<PgfConcr> concr =
namespace_lookup(pgf->concretes, name);
namespace_lookup_index(pgf->concretes, name, &index);
if (concr == 0)
throw pgf_error("Unknown concrete syntax");

concr = clone_concrete(pgf, concr);

object rev = db->register_revision(concr.tagged(), PgfDB::get_txn_id());
object rev = db->register_concr_revision(revision, index);
db->ref_count++;
return rev;
} PGF_API_END
Expand Down
Loading

0 comments on commit 43671f3

Please sign in to comment.