<html><body><div style="font-family: times new roman, new york, times, serif; font-size: 14pt; color: #000000"><div><div>In a project of mine, I have used the gettext module from Python Standard Library. I have found that several tools could be used to generate the Machine Object (mo) file from the source Portable Object (one): pybabel (<span class="Object" id="OBJ_PREFIX_DWT68_com_zimbra_url"><a href="http://babel.pocoo.org/en/latest/" target="_blank" data-mce-href="http://babel.pocoo.org/en/latest/">http://babel.pocoo.org/en/latest/</a></span>), msgfmt.py from Python tools or the original msgfmt from GNU gettext.</div><div><br></div><div>I could find that only the original msgfmt was able to generate a hashtable, and that anyway the Python gettext module loaded everything in memory and did not use it. But I also find a TODO note saying</div><div><br></div><span style="font-family: times new roman, new york, times, serif;" data-mce-style="font-family: times new roman, new york, times, serif;"># TODO:</span><br><span style="font-family: times new roman, new york, times, serif;" data-mce-style="font-family: times new roman, new york, times, serif;"># - Lazy loading of .mo files.  Currently the entire catalog is loaded into</span><br><span style="font-family: times new roman, new york, times, serif;" data-mce-style="font-family: times new roman, new york, times, serif;">#   memory, but that's probably bad for large translated programs.  Instead,</span><br><span style="font-family: times new roman, new york, times, serif;" data-mce-style="font-family: times new roman, new york, times, serif;">#   the lexical sort of original strings in GNU .mo files should be exploited</span><br><span style="font-family: times new roman, new york, times, serif;" data-mce-style="font-family: times new roman, new york, times, serif;">#   to do binary searches and lazy initializations.  Or you might want to use</span><br><span style="font-family: times new roman, new york, times, serif;" data-mce-style="font-family: times new roman, new york, times, serif;">#   the undocumented double-hash algorithm for .mo files with hash tables, but</span><br><span style="font-family: times new roman, new york, times, serif;" data-mce-style="font-family: times new roman, new york, times, serif;">#   you'll need to study the GNU gettext code to do this.</span><br><div><br></div><div>I have studied GNU gettext code and found that implemententing the hashing algorithm in Python would not be that hard.</div><div><br></div><div>The undocumented features required for implementation are:</div><div>- the version number can safely stay to 0 when processing Python code</div><div>- the size of the hash table is the first odd prime greater than or equal to 4 * n / 3 where n is the number of strings</div><div>- the first hashing function uses a variant of PJW hash function described in <span class="Object" id="OBJ_PREFIX_DWT69_com_zimbra_url"><a href="https://en.wikipedia.org/wiki/PJW_hash_function," target="_blank" data-mce-href="https://en.wikipedia.org/wiki/PJW_hash_function,">https://en.wikipedia.org/wiki/PJW_hash_function,</a></span> where the line <span class="n">h</span> <span class="o">=</span> <span class="n">h</span> <span class="err">&</span> <span class="err">~</span><span class="nb">high</span> is replaced with h = h ^ high, and using 32 bits integers. The index in the table in the result of the function modulus the size of the hash table</div><div>- when there is a conflict (the slot given by the first hashing function is already used by another string) the following is used:</div><div>  - let h be the result of the PJW variant hash function and size be the size of the hash table, an increment value is set to 1 +( h % (size -2))</div><div>  - that increment is repeatedly added to the index in the hash table (modulus the table size) until an empty slot is found (or the correct original string is found)<br></div><div><br></div><div>For now, my (alpha) code is able to generate in pure Python the same mo file that GNU msgfmt generates, and use the hashtable to access the strings.</div><div><br></div><div>Remaining problems:</div><div>- I had to read GPL copyrighted code to find the undocumented features. I have of course wrote my own code from scratch, but may I use an Apache Free License 2.1 on it?</div>- the current code for gettext loads everything from the mo file and immediately closes it. My own code keeps the file opened to be able to access it with the mmap module. There could be use case where first option is better<br></div><div>- I should either rely on the current way (load everything in memory) or implement a binary search algo for the case where the hash table is not present (it is of course optional)<br></div><div>- it would be an important change, and I think that options should be allow to choose between an eager or lazy access<br></div><div><br></div><div>Before going further, I would like to know whether implementing lazy access through the hash table that way seems to be a interesting improvement or a dead end.<br></div></div></body></html>