// hash_workload.cm — Hash-heavy / word-count / map-reduce kernel
// Stresses record (object) creation, property access, and string handling.

function make_words(count) {
  // Generate a repeating word list to simulate text processing
  var base_words = [
    "the", "quick", "brown", "fox", "jumps", "over", "lazy", "dog",
    "and", "cat", "sat", "on", "mat", "with", "hat", "bat",
    "alpha", "beta", "gamma", "delta", "epsilon", "zeta", "eta", "theta",
    "hello", "world", "foo", "bar", "baz", "qux", "quux", "corge"
  ]
  var words = []
  var i = 0
  for (i = 0; i < count; i++) {
    push(words, base_words[i % length(base_words)])
  }
  return words
}

// Word frequency count
function word_count(words) {
  var freq = {}
  var i = 0
  var w = null
  for (i = 0; i < length(words); i++) {
    w = words[i]
    if (freq[w]) {
      freq[w] = freq[w] + 1
    } else {
      freq[w] = 1
    }
  }
  return freq
}

// Find top-N words by frequency
function top_n(freq, n) {
  var keys = array(freq)
  var pairs = []
  var i = 0
  for (i = 0; i < length(keys); i++) {
    push(pairs, {word: keys[i], count: freq[keys[i]]})
  }
  var sorted = sort(pairs, "count")
  // Return last N (highest counts)
  var result = []
  var start = length(sorted) - n
  if (start < 0) start = 0
  for (i = start; i < length(sorted); i++) {
    push(result, sorted[i])
  }
  return result
}

// Histogram: group words by length
function group_by_length(words) {
  var groups = {}
  var i = 0
  var w = null
  var k = null
  for (i = 0; i < length(words); i++) {
    w = words[i]
    k = text(length(w))
    if (!groups[k]) groups[k] = []
    push(groups[k], w)
  }
  return groups
}

// Simple hash table with chaining (stress property access patterns)
function hash_table_ops(n) {
  var table = {}
  var i = 0
  var k = null
  var collisions = 0

  // Insert phase
  for (i = 0; i < n; i++) {
    k = `key_${i % 512}`
    if (table[k]) collisions++
    table[k] = i
  }

  // Lookup phase
  var found = 0
  for (i = 0; i < n; i++) {
    k = `key_${i % 512}`
    if (table[k]) found++
  }

  // Delete phase
  var deleted = 0
  for (i = 0; i < n; i += 3) {
    k = `key_${i % 512}`
    if (table[k]) {
      delete table[k]
      deleted++
    }
  }

  return found - deleted + collisions
}

var words_1k = make_words(1000)
var words_10k = make_words(10000)

return {
  // Word count on 1K words
  wordcount_1k: function(n) {
    var i = 0
    var freq = null
    for (i = 0; i < n; i++) {
      freq = word_count(words_1k)
    }
    return freq
  },

  // Word count on 10K words
  wordcount_10k: function(n) {
    var i = 0
    var freq = null
    for (i = 0; i < n; i++) {
      freq = word_count(words_10k)
    }
    return freq
  },

  // Word count + top-10 extraction
  wordcount_top10: function(n) {
    var i = 0
    var freq = null
    var top = null
    for (i = 0; i < n; i++) {
      freq = word_count(words_10k)
      top = top_n(freq, 10)
    }
    return top
  },

  // Group words by length
  group_by_len: function(n) {
    var i = 0
    var groups = null
    for (i = 0; i < n; i++) {
      groups = group_by_length(words_10k)
    }
    return groups
  },

  // Hash table insert/lookup/delete
  hash_table: function(n) {
    var i = 0
    var x = 0
    for (i = 0; i < n; i++) {
      x += hash_table_ops(2048)
    }
    return x
  }
}
