[A68-RECUTILS][COMMITTED] Add rec-field-name.a68
Jose E. Marchesi
jemarch@gnu.org
Sun Apr 6 12:05:03 GMT 2025
---
src/rec-field-name.a68 | 70 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 70 insertions(+)
create mode 100644 src/rec-field-name.a68
diff --git a/src/rec-field-name.a68 b/src/rec-field-name.a68
new file mode 100644
index 0000000..6a762ae
--- /dev/null
+++ b/src/rec-field-name.a68
@@ -0,0 +1,70 @@
+# rec-field-name.a68 - GNU recutils - field names.
+
+ Copyright (C) 2025 Jose E. Marchesi.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+#
+
+# Field names are shared and organized in a hash table. #
+
+INT rec hash size = 1008;
+[rec hash size]REF REC_FIELD_NAME rec field names;
+
+# A REC_FIELD_NAME denotes a field name.
+
+ "chain" is used to chain field names together in "rec fields".
+#
+
+MODE REC_FIELD_NAME = STRUCT (STRING name, REF REC_FIELD_NAME chain);
+
+# Nihils. #
+
+REF REC_FIELD_NAME rec no field name = NIL;
+
+# Get a rec field name given a string. #
+
+PROC rec get field name = (STRING name) REF REC_FIELD_NAME:
+BEGIN ASSERT (name /= "");
+
+ INT hash = rec hash string (name);
+
+ # First try to find an existing field name with this name. #
+ REF REC_FIELD_NAME field name := rec field names[hash];
+ WHILE field name :/=: rec no field name
+ DO IF name OF field name = name THEN found FI;
+ field name := chain OF field name
+ OD;
+
+ # Not found. Add it to the hash bucket. #
+ field name := HEAP REC_FIELD_NAME := (name, rec field names[hash]);
+ rec field names[hash] := field name;
+found:
+ field name
+END;
+
+# Hash a given string. #
+
+PROC rec hash string = (STRING str) INT:
+BEGIN INT len = UPB str;
+ BITS hash := BIN len;
+
+ FOR i TO len
+ DO hash := BIN ((ABS hash * 613) + ABS str[i]) OD;
+
+ INT hashbits = 30;
+ hash := BIN (ABS (hash AND (BIN 1 SHL hashbits)) - 1);
+ hash := BIN (ABS hash %* rec hash size);
+ ABS hash
+END;
--
2.30.2
More information about the Algol68
mailing list