diff --git a/packages/ludic.jobs/facts.ludic b/packages/ludic.jobs/facts.ludic new file mode 100644 index 00000000..23f67446 --- /dev/null +++ b/packages/ludic.jobs/facts.ludic @@ -0,0 +1,19 @@ +# facts.ludic - a jobs fact's record: one no drain holds any more, made fresh (and kept) only when +# every one is held. A deed that moves a job is a fact, and a record a fact is never given back +# (the ludic.wildlife idiom) +function jobs__fact_record(jobs_st: mut JobsState) -> JobsFact { + if jobs_st.jobs__fnext[0] >= len(jobs_st.jobs__ffree) { + q_unheld(jobs_st.jobs__q, jobs_st.jobs__fpool, jobs_st.jobs__ffree) + jobs_st.jobs__fnext[0] = 0 + } + if jobs_st.jobs__fnext[0] < len(jobs_st.jobs__ffree) { + let f = jobs_st.jobs__ffree[jobs_st.jobs__fnext[0]] + jobs_st.jobs__fnext[0] += 1 + return f + } + let f = new JobsFact + push(jobs_st.jobs__fpool, f) + return f +} +# how many fact records have ever been made: the peak held at once, not the facts said +export function jobs_fact_records(jobs_st: JobsState) -> int { return len(jobs_st.jobs__fpool) } diff --git a/packages/ludic.jobs/index.ludic b/packages/ludic.jobs/index.ludic index 6ff8a86a..30203e2b 100644 --- a/packages/ludic.jobs/index.ludic +++ b/packages/ludic.jobs/index.ludic @@ -6,6 +6,7 @@ import "ludic.base" import "defs.ludic" import "ports.ludic" import "state.ludic" +import "facts.ludic" import "jobs.ludic" import "giveup.ludic" import "count.ludic" diff --git a/packages/ludic.jobs/state.ludic b/packages/ludic.jobs/state.ludic index 370701f2..509038c8 100644 --- a/packages/ludic.jobs/state.ludic +++ b/packages/ludic.jobs/state.ludic @@ -22,6 +22,9 @@ export state JobsState { jobs__seed: int = 1000 jobs__dice: Rng = rng_new(1000) jobs__q: Queue = jobs__q__new() + jobs__fpool: []JobsFact = new []JobsFact # every fact record made, reused once no drain holds it (facts.ludic) + jobs__ffree: []JobsFact = new []JobsFact + jobs__fnext: []int = words(1) } # the posts, every board's slots end to end from jobs__off[b] @@ -58,8 +61,8 @@ export function jobs_facts(jobs_st: JobsState) -> Queue { return jobs_st.jobs__q } -function jobs__fact(jobs_st: JobsState, what: int, job: int, b: int, s: int, have: int, need: int) -> void { - let f = new JobsFact +function jobs__fact(jobs_st: mut JobsState, what: int, job: int, b: int, s: int, have: int, need: int) -> void { + let f = jobs__fact_record(jobs_st) f.what = what f.job = job f.board = b diff --git a/packages/ludic.jobs/tests/giveup_test.ludic b/packages/ludic.jobs/tests/giveup_test.ludic index 96b83c66..49a600b6 100644 --- a/packages/ludic.jobs/tests/giveup_test.ludic +++ b/packages/ludic.jobs/tests/giveup_test.ludic @@ -129,4 +129,17 @@ program JobsGiveUpTest { jobs_test_st.day = 2 expect(jobs_offered(jobs_st, JOB_CATCH)) } + + test "two hundred jobs taken and given up, their facts drained each time, reuse a handful of records" (jobs_st: mut JobsState, jobs_test_st: mut JobsTestState) { + fresh(jobs_st, jobs_test_st) + for k in 0 .. 200 { + jobs_take(jobs_st, JOB_CATCH) + count_of(jobs_st, 0) + jobs_give_up(jobs_st, JOB_CATCH) + count_of(jobs_st, 0) + jobs_st.jobs__back[JOB_CATCH] = -1 + } + print(`jobs: 200 taken and given up, {jobs_fact_records(jobs_st)} fact records made`) + expect(jobs_fact_records(jobs_st) < 10) + } }