[{"data":1,"prerenderedAt":438},["ShallowReactive",2],{"project-42359949":3},{"id":4,"name":5,"line":6,"line_source":7,"title":8,"url":9,"domain":10,"maker":11,"posted_at":12,"year":13,"points":14,"comments":15,"rank_in_year":16,"shown_in_year":17,"top":18,"tier":19,"category":20,"subcategory":21,"format":22,"keywords":23,"reception":28,"sentiment":29,"stance_mix":30,"scored_comments":35,"aspects":36,"strip":43,"post_text":46,"what":47,"said":69,"maker_in_thread":190,"shape":199,"grid":204,"attempts":399,"same_week":400,"maker_shows":31,"maker_hidden":430,"reader_version":431,"card":432},"42359949","salmagundi","A portable hash map in C","title","Show HN: A portable hash map in C","https:\u002F\u002Fgithub.com\u002Fe-dant\u002Fsalmagundi","github.com","e-dant",1733688325,2024,176,90,457,3515,14,"notable","languages","c hash map library","library",[24,25,26,27],"c hash map","linear probing","portable c library","hash table c","curious",-0.221,{"positive":31,"neutral":32,"mixed":33,"critical":34},2,24,1,10,37,{"execution":37,"design":40,"performance":41,"docs":42},{"positive":38,"critical":39},0,6,{"positive":33,"critical":31},{"positive":38,"critical":33},{"positive":38,"critical":33},[44,38,38,33,33,44,44,33,33,33,33,44,38,44,45,44,44,44,38,38,38,38,44,38,38,44,33,33,44,44,44,44,44,44,44,38,38,44,44,44],3,5,null,{"problem":46,"audience":48,"pricing":46,"motivation":55,"time_to_build":46,"stack":60,"openness":66,"stage":67,"team_size":68},{"value":49,"source":50,"evidence":51},"C developers who want a simple hash map","inferred",[52],{"id":53,"by":11,"text":54},"42360267","I like the exercise of trying to find the simplest reasonable solution to some problem. Many of my toy and hobby projects are exactly that. Some make allowances for the sake of…",{"value":56,"source":57,"evidence":58},"A simple, cute hash map exercise and toy project","maker",[59],{"id":53,"by":11,"text":54},[61],{"value":62,"source":50,"evidence":63},"C",[64],{"id":65},"post","open_source","prototype","unknown",{"praise":70,"objections":83,"requests":126,"questions":150,"alternatives":176},[71,79],{"value":72,"source":73,"evidence":74},"Simple and remarkably small implementation","commenter",[75],{"id":76,"by":77,"text":78},"42360148","vintagedave","This is neat, and remarkably small. I personally need more comments in order to follow, say, the growth logic. I see it rehashes but I don't see how it doesn't potentially…",{"value":80,"source":73,"evidence":81},"Name is a nice word choice",[82],{"id":76,"by":77,"text":78},[84,99,111,122],{"value":85,"source":73,"evidence":86},"Deletion is broken: deleting a colliding item makes later items unfindable",[87,91,95],{"id":88,"by":89,"text":90},"42360417","drfuchs","A bug, I believe: If you \"put\" three colliding strings A and then B and then C, and then \"delete\" B, you won't be able to find C anymore.",{"id":92,"by":93,"text":94},"42362450","attractivechaos","You are implementing a closed hash table with linear probing. You need tombstones to mark deleted items, or better, move other items to replace deleted items [1]. Currently your…",{"id":96,"by":97,"text":98},"42361832","teo_zero","Row 100 of hm_put() clears all contents of the item struct, thus losing the pointer to where the previous value was stored. But then row 107 needs this pointer to pass it to…",{"value":100,"source":73,"evidence":101},"Memory bugs in hm_put including lost pointers and key leaks",[102,103,107],{"id":96,"by":97,"text":98},{"id":104,"by":105,"text":106},"42361428","tralarpa","My C is quite rusty, so apologies for stupid questions. In the hm_put function, when you overwrite, why do you malloc and copy the key again, and what happens with the old key…",{"id":108,"by":109,"text":110},"42366162","ms9598","In reviewing hm_put, a few things stand out in the area of handling cases where memory allocation fails. The first problems are at lines 113-116 where memory is allocated and…",{"value":112,"source":73,"evidence":113},"Many mallocs hurt performance",[114,118],{"id":115,"by":116,"text":117},"42363325","cozzyd","I'm curious about the #ifdef guard, which is of a form I've never encountered. ``` #ifndef BD9DF82A4540BB19368E48E4747C0706 #define BD9DF82A4540BB19368E48E4747C0706 ``` Does some…",{"id":119,"by":120,"text":121},"42360562","jll29","Thanks for sharing. Simplicity is a good thing. In order to speed it up by reducing the number of malloc() calls, it may be worth adding a simple arena memory allocation measure:…",{"value":123,"source":73,"evidence":124},"Missing comments make the code hard to follow",[125],{"id":76,"by":77,"text":78},[127,135,146],{"value":128,"source":73,"evidence":129},"Fix deletion using tombstones or slot shifting",[130,131],{"id":92,"by":93,"text":94},{"id":132,"by":133,"text":134},"42364284","skitter","Another solution could be tombstones: When a slot gets cleared and the next slot has an item, insert a placeholder value. During linear probing, treat the placeholder as a normal…",{"value":136,"source":73,"evidence":137},"Add fuzz tests or valgrind testing",[138,142],{"id":139,"by":140,"text":141},"42361871","gritzko","I recently coded a linear-probing hash map in C and I highly recommend you to use fuzz tests. These evolve naturally from unit tests: next step table unit tests, next step…",{"id":143,"by":144,"text":145},"42361513","codr7","Considering there seems to be at least a one memory bug (hm_put\u002Fkey from another comment), I would strongly recommend running the tests in valgrind or similar if you haven't…",{"value":147,"source":73,"evidence":148},"Use an arena allocator to reduce mallocs",[149],{"id":119,"by":120,"text":121},[151,161,169],{"value":152,"source":73,"evidence":153},"Why unused parameters and (void) casts in hash functions",[154,158],{"id":155,"by":156,"text":157},"42360571","zabzonk","Purely out of interest, and probably my bad, but what is: ``` (void)k_sz; ``` doing? I've seen fussy people doing: ``` (void) printf( \"hello\" ); ``` but not what you have…",{"id":159,"by":156,"text":160},"42360759","OK, thank you. But why do the functions have those unused parameters?",{"value":162,"source":73,"evidence":163},"Why use an MD5-length random include guard instead of pragma once",[164,165],{"id":115,"by":116,"text":117},{"id":166,"by":167,"text":168},"42364118","tobyhinloopen","What's wrong with `#pragma once`? (honest question, i only do C and C++ as a hobby)",{"value":170,"source":73,"evidence":171},"How to handle padding bytes when hashing structs",[172],{"id":173,"by":174,"text":175},"42364709","eqvinox","Here's some food-for-thought questions: First, a correctness question: - if a struct contains padding, the value of these padding bytes is undefined. What happens if you use such…",[177,183],{"value":178,"source":73,"evidence":179},"Chained hash maps, which make deletion simpler",[180],{"id":181,"by":174,"text":182},"42364753","> Finally, deletes are hard in hash maps. Deletes are hard in open hash maps like here; they're trivial in chained hash maps. (I'm only posting this because this seems to be an…",{"value":184,"source":73,"evidence":185},"Crafting Interpreters hash table chapter",[186],{"id":187,"by":188,"text":189},"42370973","munificent","If it helps, my book Crafting Interpreters walks through a linear probing hash table implementation in C including handling deletion:…",{"comments":39,"answered":33,"key":191},[192,195,196],{"id":193,"text":194},"42360455","Good catch! Yes, that looks like a bug :)",{"id":53,"text":54},{"id":197,"text":198},"42360401","There’s no slot cycling logic. When a k,v pair at some index is deleted, and a different k,v pair has a matching hash, there’s a (small?) penalty in the hm_get logic that will…",{"commenters":200,"max_depth":201,"maker_replies":39,"first_comment_mins":202,"lifespan_hours":203},44,9,25,52,[205,207,211,214,217,219,222,224,225,226,227,229,232,234,236,238,240,242,244,246,249,253,254,258,261,263,265,267,270,272,274,275,278,280,281,284,286,289,291,293,295,298,301,304,307,310,312,314,316,318,320,322,324,327,328,332,336,341,344,346,349,352,355,358,361,364,366,367,369,371,374,376,378,380,383,386,389,393,396],[139,38,44,206,140,38],"maker\u002Fneutral\u002Fexecution",[208,38,38,209,210,38],"42362138","other\u002Fneutral\u002Fnone","dwattttt",[212,38,38,213,174,38],"42364808","commenter\u002Fneutral\u002Fexecution",[215,38,38,213,216,38],"42365491","cb321",[218,38,38,213,174,38],"42366040",[220,38,38,221,216,38],"42366662","commenter\u002Fneutral\u002Fperformance",[88,33,33,223,89,38],"project\u002Fcritical\u002Fexecution",[193,33,38,206,11,33],[92,33,33,223,93,38],[187,33,38,209,188,38],[173,31,44,228,174,38],"project\u002Fneutral\u002Fdesign",[230,31,44,228,231,38],"42370218","hoten",[233,31,44,228,174,38],"42371033",[119,44,44,235,120,38],"project\u002Fneutral\u002Fperformance",[237,44,33,223,93,38],"42362436",[96,239,33,223,97,38],4,[181,239,33,241,174,38],"project\u002Fcritical\u002Fdesign",[243,239,33,241,97,38],"42370741",[245,239,38,221,174,38],"42374772",[247,239,33,248,97,38],"42382351","project\u002Fcritical\u002Fperformance",[250,239,38,251,252,38],"42366227","other\u002Fcritical\u002Fnone","acmj",[143,45,44,206,144,38],[255,45,38,256,257,38],"42370666","commenter\u002Fneutral\u002Fnone","ivanjermakov",[259,45,38,256,260,38],"42372225","chlorion",[262,45,38,256,144,38],"42383121",[76,39,44,264,77,38],"project\u002Fmixed\u002Fdesign",[53,39,38,266,11,33],"maker\u002Fpositive\u002Fidea",[268,39,45,269,77,38],"42360303","project\u002Fpositive\u002Fdesign",[197,39,38,271,11,33],"project\u002Fneutral\u002Fexecution",[273,39,38,223,11,33],"42360502",[132,39,44,271,133,38],[276,39,38,209,277,38],"42365133","andrelaszlo",[115,279,44,228,116,38],7,[166,279,44,228,167,38],[282,279,38,256,283,38],"42364405","Gibbon1",[285,279,38,256,174,38],"42364729",[287,279,38,256,288,38],"42365544","kevin_thibedeau",[290,279,38,256,174,38],"42366003",[292,279,38,256,288,38],"42366311",[294,279,38,256,174,38],"42366404",[296,279,38,256,297,38],"42364644","emsy",[299,279,38,256,300,38],"42369130","uecker",[302,279,38,256,303,38],"42370811","iainmerrick",[305,279,44,228,306,38],"42365372","heavensteeth",[308,279,38,256,309,38],"42368368","quotemstr",[311,279,38,256,300,38],"42369096",[313,279,38,256,309,38],"42369430",[315,279,38,256,303,38],"42370803",[317,279,38,256,300,38],"42371385",[319,279,38,256,116,38],"42370657",[104,321,44,271,105,38],8,[323,321,44,206,144,38],"42361492",[325,201,33,223,326,38],"42361773","alanmoraes",[108,34,33,223,109,38],[329,330,38,331,11,33],"42362340",11,"maker\u002Fneutral\u002Fnone",[333,330,45,334,335,38],"42362738","maker\u002Fpositive\u002Fnone","rhelz",[337,338,33,339,340,38],"42360141",12,"project\u002Fcritical\u002Fdocs","EricRiese",[342,338,38,343,11,33],"42360230","maker\u002Fneutral\u002Fdocs",[155,345,44,271,156,38],13,[347,345,44,271,348,38],"42360600","ryanpetrich",[350,345,44,271,351,38],"42360614","lang4d",[353,345,44,271,354,38],"42360617","secondcoming",[356,345,44,271,357,38],"42360642","tester756",[359,345,44,271,360,38],"42360655","Sesse__",[362,345,38,256,363,38],"42360732","tredre3",[365,345,38,256,360,38],"42360764",[159,345,44,228,156,38],[368,345,44,228,360,38],"42360783",[370,345,44,228,156,38],"42360829",[372,345,38,373,360,38],"42360880","commenter\u002Fneutral\u002Fdesign",[375,345,38,373,156,38],"42360985",[377,345,38,373,360,38],"42368301",[379,345,38,373,156,38],"42371182",[381,345,38,373,382,38],"42360901","saagarjha",[384,345,44,228,385,38],"42361515","detaro",[387,18,38,209,388,38],"42362237","david2ndaccount",[390,391,44,271,392,38],"42362224",15,"TheDudeMan",[394,391,44,235,395,38],"42362253","meisel",[397,398,38,209,309,38],"42368963",16,[],[401,406,410,415,420,425],{"id":402,"name":403,"points":404,"category":405},"42348513","Countless.dev",361,"ai",{"id":407,"name":408,"points":409,"category":405},"42356443","Cut the crap",356,{"id":411,"name":412,"points":413,"category":414},"42331270","Banan-OS",333,"infrastructure",{"id":416,"name":417,"points":418,"category":419},"42338327","Hacker Herald",251,"consumer_social",{"id":421,"name":422,"points":423,"category":424},"42329071","gitingest",185,"dev_tools",{"id":426,"name":427,"points":428,"category":429},"42382506","ideaharbor",171,"web_saas",false,"v2",{"id":433,"name":5,"line":6,"ai":430,"cat":20,"year":13,"points":14,"comments":15,"rec":28,"s":434,"top":18,"kw":435,"maker":11,"domain":10,"tier":19,"attempts":38,"strip":436,"url":9,"mix":437,"praise":72,"objection":85,"sub":21},42359949,-0.22,[24,25,26,27],"3001133111130353330000300311333333300333",[31,32,33,34],1794036665565]