Skip to content

Commit

Permalink
Merge pull request #7 from billowdev/feat-exact-values-by-keys
Browse files Browse the repository at this point in the history
Add ComboKeyHashMap Functionality
  • Loading branch information
billowdev authored Jan 29, 2025
2 parents f13e0e8 + 131c351 commit cf6ba6c
Show file tree
Hide file tree
Showing 3 changed files with 381 additions and 79 deletions.
101 changes: 66 additions & 35 deletions coverage.html
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@

<option value="file1">github.com/billowdev/fastmap/hashmap/appendable_threadsafe.go (8.3%)</option>

<option value="file2">github.com/billowdev/fastmap/hashmap/combination.go (98.0%)</option>
<option value="file2">github.com/billowdev/fastmap/hashmap/combination.go (92.4%)</option>

<option value="file3">github.com/billowdev/fastmap/hashmap/config_operation_threadsafe.go (100.0%)</option>

Expand All @@ -85,7 +85,7 @@

<option value="file14">github.com/billowdev/fastmap/hashmap/operations.go (95.5%)</option>

<option value="file15">github.com/billowdev/fastmap/robinhood/robinhood.go (93.2%)</option>
<option value="file15">github.com/billowdev/fastmap/robinhood/robinhood.go (90.5%)</option>

<option value="file16">github.com/billowdev/fastmap/sample/main.go (0.0%)</option>

Expand Down Expand Up @@ -573,7 +573,7 @@

// Put associates a value with a combination of keys
func (m *ComboKeyHashMap[K, V]) Put(keys []K, value V) <span class="cov8" title="1">{
if len(keys) == 0 </span><span class="cov0" title="0">{
if len(keys) == 0 </span><span class="cov8" title="1">{
return
}</span>

Expand All @@ -596,44 +596,37 @@
return val, exists
}</span>

// GetByKeys retrieves all values where all provided keys are part of the key group
func (m *ComboKeyHashMap[K, V]) GetByKeys(keys []K) []V <span class="cov8" title="1">{
// GetByKeys retrieves a value where provided keys are part of the key group
func (m *ComboKeyHashMap[K, V]) GetByKeys(keys []K) (V, bool) <span class="cov8" title="1">{
if len(keys) == 0 </span><span class="cov8" title="1">{
return []V{}
var zero V
return zero, false
}</span>

// Track unique values using a map to avoid duplicates
<span class="cov8" title="1">valueMap := make(map[string]V)

// Check each key's groups
for _, key := range keys </span><span class="cov8" title="1">{
groups := m.keyGroups[key]
for _, group := range groups </span><span class="cov8" title="1">{
// Check if all provided keys are in this group
allKeysFound := true
for _, searchKey := range keys </span><span class="cov8" title="1">{
if !contains(group, searchKey) </span><span class="cov8" title="1">{
allKeysFound = false
break</span>
}
// Check first key's groups
<span class="cov8" title="1">firstKey := keys[0]
groups := m.keyGroups[firstKey]

for _, group := range groups </span><span class="cov8" title="1">{
// Check if all provided keys are in this group
allKeysFound := true
for _, searchKey := range keys </span><span class="cov8" title="1">{
if !contains(group, searchKey) </span><span class="cov0" title="0">{
allKeysFound = false
break</span>
}
}

<span class="cov8" title="1">if allKeysFound </span><span class="cov8" title="1">{
keyString := m.generateKeyString(group)
if val, exists := m.data[keyString]; exists </span><span class="cov8" title="1">{
valueMap[keyString] = val
}</span>
}
<span class="cov8" title="1">if allKeysFound </span><span class="cov8" title="1">{
keyString := m.generateKeyString(group)
if val, exists := m.data[keyString]; exists </span><span class="cov8" title="1">{
return val, true
}</span>
}
}

// Convert map to slice
<span class="cov8" title="1">result := make([]V, 0, len(valueMap))
for _, v := range valueMap </span><span class="cov8" title="1">{
result = append(result, v)
}</span>

<span class="cov8" title="1">return result</span>
<span class="cov8" title="1">var zero V
return zero, false</span>
}

// Helper functions
Expand All @@ -644,7 +637,7 @@
return true
}</span>
}
<span class="cov8" title="1">return false</span>
<span class="cov0" title="0">return false</span>
}

func sortSlice[K comparable](slice []K) <span class="cov8" title="1">{
Expand All @@ -659,6 +652,44 @@
}

type KeyGroup[K comparable] []K

// GetByExactKeys retrieves a value where provided keys exactly match a key group
func (m *ComboKeyHashMap[K, V]) GetByExactKeys(keys []K) (V, bool) <span class="cov8" title="1">{
if len(keys) == 0 </span><span class="cov8" title="1">{
var zero V
return zero, false
}</span>

// Check first key's groups
<span class="cov8" title="1">firstKey := keys[0]
groups := m.keyGroups[firstKey]

for _, group := range groups </span><span class="cov8" title="1">{
// First check if lengths match - all keys must be present
if len(group) != len(keys) </span><span class="cov8" title="1">{
continue</span>
}

// Check if all provided keys are in this group
<span class="cov8" title="1">allKeysFound := true
for _, searchKey := range keys </span><span class="cov8" title="1">{
if !contains(group, searchKey) </span><span class="cov0" title="0">{
allKeysFound = false
break</span>
}
}

<span class="cov8" title="1">if allKeysFound </span><span class="cov8" title="1">{
keyString := m.generateKeyString(group)
if val, exists := m.data[keyString]; exists </span><span class="cov8" title="1">{
return val, true
}</span>
}
}

<span class="cov8" title="1">var zero V
return zero, false</span>
}
</pre>

<pre class="file" id="file3" style="display: none">package fastmap
Expand Down Expand Up @@ -1964,7 +1995,7 @@
entry = &amp;m.entries[index]</span>
}
}
<span class="cov8" title="1">dist++
<span class="cov0" title="0">dist++
index = (index + 1) &amp; m.mask</span>
}
}
Expand Down
89 changes: 60 additions & 29 deletions hashmap/combination.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,44 +58,37 @@ func (m *ComboKeyHashMap[K, V]) Get(keys []K) (V, bool) {
return val, exists
}

// GetByKeys retrieves all values where all provided keys are part of the key group
func (m *ComboKeyHashMap[K, V]) GetByKeys(keys []K) []V {
// GetByKeys retrieves a value where provided keys are part of the key group
func (m *ComboKeyHashMap[K, V]) GetByKeys(keys []K) (V, bool) {
if len(keys) == 0 {
return []V{}
var zero V
return zero, false
}

// Track unique values using a map to avoid duplicates
valueMap := make(map[string]V)

// Check each key's groups
for _, key := range keys {
groups := m.keyGroups[key]
for _, group := range groups {
// Check if all provided keys are in this group
allKeysFound := true
for _, searchKey := range keys {
if !contains(group, searchKey) {
allKeysFound = false
break
}
// Check first key's groups
firstKey := keys[0]
groups := m.keyGroups[firstKey]

for _, group := range groups {
// Check if all provided keys are in this group
allKeysFound := true
for _, searchKey := range keys {
if !contains(group, searchKey) {
allKeysFound = false
break
}
}

if allKeysFound {
keyString := m.generateKeyString(group)
if val, exists := m.data[keyString]; exists {
valueMap[keyString] = val
}
if allKeysFound {
keyString := m.generateKeyString(group)
if val, exists := m.data[keyString]; exists {
return val, true
}
}
}

// Convert map to slice
result := make([]V, 0, len(valueMap))
for _, v := range valueMap {
result = append(result, v)
}

return result
var zero V
return zero, false
}

// Helper functions
Expand All @@ -121,3 +114,41 @@ func sortSlice[K comparable](slice []K) {
}

type KeyGroup[K comparable] []K

// GetByExactKeys retrieves a value where provided keys exactly match a key group
func (m *ComboKeyHashMap[K, V]) GetByExactKeys(keys []K) (V, bool) {
if len(keys) == 0 {
var zero V
return zero, false
}

// Check first key's groups
firstKey := keys[0]
groups := m.keyGroups[firstKey]

for _, group := range groups {
// First check if lengths match - all keys must be present
if len(group) != len(keys) {
continue
}

// Check if all provided keys are in this group
allKeysFound := true
for _, searchKey := range keys {
if !contains(group, searchKey) {
allKeysFound = false
break
}
}

if allKeysFound {
keyString := m.generateKeyString(group)
if val, exists := m.data[keyString]; exists {
return val, true
}
}
}

var zero V
return zero, false
}
Loading

0 comments on commit cf6ba6c

Please sign in to comment.