[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