except for all of those innocent folks that have had their lives ruined by that 'almost all the time' caveat, it's great!
here's a report[0] that says something like 80% + of criminal forensic work has major mistakes within it.
[0]: https://www.criminallegalnews.org/news/2024/may/15/report-fi...
I double-checked the forensics work and found several mistakes in processes, assumptions and technical conclusions. I sent off my findings to people associated with Project Innocence - not because I found anything that proved Cooper or Anthony's innocence, quite the opposite. Instead, I wanted to let them know that forensics experts can make mistakes.
It is interesting that scientific work have fault-finding processes like peer-reviews, but forensics investigations in court cases does not.
- The absence of free-floating functions (everything is an object, and I must use static methods on static classes).
- When “using” a namespace, the convention is to make all the symbols in the “used” namespace available directly in the current namespace. That makes harder to know where symbols are coming from when reading code. And to avoid name collisions, people tend to use longer names. The convention in Go or Rust is to prefix most symbols with the package they are coming from. But perhaps I’m missing something and need to read/write more C#.
- The syntax for doc comments with tags such as <summary> is super verbose. I don’t see the point. Docs are working great without these tags in other languages. Reminds me of my J2EE days.
- I really prefer the name before type syntax (used in all new languages such as Go, TypeScript, Go, Swift, Kotlin, Zig, etc.) to the type before name syntax (used in C#, C, C++, Java, Dart).
I assume that free-floating functions are global functions. You can achieve something similar by "global using". Put this in a file and tug it away somewhere:
"global using static YourStaticClass;"
Now you can call all the static methods on the class everywhere.
As for the using vs. naming convention, most people use the IDE and hover the mouse over the type to see its identity. Once you get proficient with the IDE, you can do it using shortcuts. However, if you really want to prefix all types with a shorthand of the package it came from, you can do it with aliases in C#.
I've been working on a few storage engine designs recently implementing an LSM tree and would like to share K4.
K4 is a storage engine written completely in GO with no dependencies. The write speed surpasses RocksDB (7.8.3) with similar configuration.
I will write way more comprehensive benchmarks down the line.
The current features of K4
------------------------------
- High speed writes and reads
- Durability
- Variable length binary keys and values. Keys and their values can be any length
- Write-Ahead Logging (WAL). System writes PUT and DELETE operations to a log file before applying them to the LSM tree.
- Atomic transactions. Multiple PUT and DELETE operations can be grouped together and applied atomically to the LSM tree.
- Paired compaction. SSTables are paired up during compaction and merged into a single SSTable(s). This reduces the number of SSTables and minimizes disk I/O for read operations.
- Memtable implemented as a skip list.
- In-memory and disk-based storage
- Configurable memtable flush threshold
- Configurable compaction interval (in seconds)
- Configurable logging
- Configurable skip list
- Bloom filter for faster lookups. SSTable initial pages contain a bloom filter. The system uses the bloom filter to determine if a key is in the SSTable before scanning the SSTable.
- Recovery from WAL
- Granular page locking
- Thread-safe
- TTL (time to live) support
- Optional compression support (Simple lightweight and optimized Lempel-Ziv 1977 inspired compression algorithm
- Range and equi functionality (Get, NGet, Range, NRange, GreaterThan, GreaterThanEq, LessThan, LessThanEq)
- No dependencies
I am in the process of writing a C binding for K4 which will enable me to write FFI's for multiple other languages like Python, Node.JS, Ruby, etc.
I hope you get a chance to check it out and do let me know your thoughts!
Thank you kindly.
If you’d like to take a look at a critical review of her other work on this topic, I’d highly recommend this damning analysis of her “Big Fat Surprise” book: https://thescienceofnutrition.wordpress.com/2014/08/10/the-b...
Here’s the diff showing what has changed: https://plugins.trac.wordpress.org/changeset?new=3167679%40a...
The original implementation [3] did the same thing but for CRC-64/XZ [4].
[1]: https://github.com/awesomized/crc64fast-nvme
[2]: https://reveng.sourceforge.io/crc-catalogue/all.htm#crc.cat....
[3]: https://github.com/tikv/crc64fast
[4]: https://reveng.sourceforge.io/crc-catalogue/all.htm#crc.cat....
[1] https://www.intel.com/content/www/us/en/docs/ipp/developer-g...
But this isn't true for all flaws. For example, even with the collision attacks against SHA-1, I don't think they're even remotely close to enabling a collision for SHA-1(some_other_hash(M)).
Similarly, HMAC-SHA-1 is still considered secure, as it's effectively SHA-1-X(SHA-1-Y(M)), where SHA-1-X and SHA-1-Y are just SHA-1 with different starting states.
So there's some value to be found in nesting hashes.
The strength of an HMAC depends on the strength of the hash function; however, since it uses two derived keys, the outer hash protects the inner hash (using the same hash function), which in turn provides protection against length extension attacks.
The case I was making, is that weakhash(stronghash(m)) has the security of weakhash, no matter how strong stronghash is.
https://github.com/Genbox/FastFilter/tree/master