Skip to content

implement dict as an Alloc allocated table#29

Merged
maximecb merged 8 commits intomaximecb:mainfrom
Maaarcocr:main
Nov 29, 2025
Merged

implement dict as an Alloc allocated table#29
maximecb merged 8 commits intomaximecb:mainfrom
Maaarcocr:main

Conversation

@Maaarcocr
Copy link
Contributor

@Maaarcocr Maaarcocr commented Nov 23, 2025

I reused rust Hash implementation for the hashing algorithm, then I used
a simply linear probing strategy to handle collisions.

I have set a threshold of 75% for when we double the size of the table.

For some reason I had to zero manually the entries of the table on creation because I was getting some dirty buffers, and some stuff was coming out as Some(...) even though we had just created an empty table.

Copy link
Owner

@maximecb maximecb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks pretty good, you did a good job, linear probing is the right choice 👍

@maximecb
Copy link
Owner

Could you also add some tests in ./tests. I put a couple of small programs prefixed with gc_ that allocate various kinds of objects to exercise the GC.

Maaarcocr added 4 commits November 29, 2025 12:03
I reused rust Hash implementation for the hashing algorithm, then I used
a simply linear probing strategy to handle collisions.

I have set a threshold of 75% for when we double the size of the table.
@Maaarcocr
Copy link
Contributor Author

Maaarcocr commented Nov 29, 2025

@maximecb sorry it took a while but i finally got hash working under gc as well. I have introduce a TableSlot struct just to have extra organisation in the dict file, so that if we want to remove the Option and use null pointers to signal that a slot is empty we can easily do that in a follow up pr.

@maximecb
Copy link
Owner

No worries Marco. Thanks for contributing :)

I fixed and tested a couple of other GC things during the week.
Also wrote examples/amigaball.psh which I am very happy with 😎

src/alloc.rs Outdated
Comment on lines +119 to +124
let p_str = self.alloc(Str::new(raw_str_ptr))?;
pub fn str(&mut self, s: &str) -> Result<*const Str, ()>
{
let inner = self.raw_str(s)?;
let p_str = self.alloc(inner)?;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you rebase the PR? I think there should be no diff in alloc.rs

Comment on lines +5 to +11
#[derive(Clone, Copy)]
struct TableSlot(Option<(*const Str, Value)>);

impl TableSlot {
fn new(key: *const Str, val: Value) -> Self {
Self(Some((key, val)))
}
Copy link
Owner

@maximecb maximecb Nov 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think probably the way I would go about this is use a null ptr for the key when the slot is empty. We could add an is_empty() method.

You can probably get rid of the option type on value and value_mut, just panic if the slot is empty? Use an assert even?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think it still makes sense to return an option for the value because it makes implementing values and values_mut with filter_map pretty easy

Copy link
Owner

@maximecb maximecb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The implementation looks good 👁️

I think the PR needs to be rebased because there are some diffs that don't match head.

I made some comments wrt TableSlot. I think it shouldn't be too hard to make the refactoring to use a null pointer for the key and it should be much cleaner. Other than that, looks ready to me 👌

@maximecb maximecb merged commit fa593bf into maximecb:main Nov 29, 2025
1 check passed
@maximecb
Copy link
Owner

I merged it and added some tests, fixed some minor bugs.

There's one thing that seems inefficient with the current implementation: the string key always gets copied on set, but that key should already be GC-allocated. The keys are also copied when expanding the table, which shouldn't be necessary.

@Maaarcocr
Copy link
Contributor Author

oh yeah good point I'll optimise that tomorrow if I get to it!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants