Skip to content
This repository has been archived by the owner on Dec 28, 2022. It is now read-only.

Commit

Permalink
Release 8th homework
Browse files Browse the repository at this point in the history
  • Loading branch information
lamtev committed Nov 14, 2022
1 parent 34c6b16 commit 90e687c
Show file tree
Hide file tree
Showing 8 changed files with 525 additions and 1 deletion.
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -195,3 +195,12 @@ $ git checkout -b <my-branch-for-part7> 0831f19beb82ce628e4f7284f8c02ce994dd0eb5
```commandline
./gradlew test
```

## ДЗ 8. Hash tables. Дедлайн 22.11.2022 18:29:59

* Реализовать в `company.vk.polis.ads.hash.SeparateChainingMap` и `company.vk.polis.ads.hash.DoubleHashingMap` методы, чтобы выполнялись все тесты в `company.vk.polis.ads.hash.MapTest`

Локально запускать тесты можно через
```commandline
./gradlew test
```
12 changes: 11 additions & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,14 @@ java {
}

dependencies {
implementation("org.jetbrains:annotations:20.1.0")
compileOnly("com.google.code.findbugs:jsr305:3.0.2")
val jetbrainsAnno = "org.jetbrains:annotations:23.0.0"
compileOnly(jetbrainsAnno)

testCompileOnly(jetbrainsAnno)
testImplementation("it.unimi.dsi:fastutil:8.5.9")
testImplementation("org.junit.jupiter:junit-jupiter-api:5.9.0")
testImplementation("org.junit.jupiter:junit-jupiter-params:5.9.0")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.9.0")

jmh("org.openjdk.jmh:jmh-core:1.35")
Expand All @@ -38,4 +43,9 @@ tasks.getByName<Test>("test") {
testLogging {
events(PASSED, SKIPPED, FAILED)
}

jvmArgs(
"--add-opens", "java.base/java.lang=ALL-UNNAMED",
"--add-opens", "java.base/java.util=ALL-UNNAMED",
)
}
76 changes: 76 additions & 0 deletions src/main/java/company/vk/polis/ads/hash/DoubleHashingMap.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package company.vk.polis.ads.hash;

import java.util.function.BiConsumer;

import org.jetbrains.annotations.Nullable;

/**
* Map implementation with double hashing collision resolution approach
*
* @param <K> key
* @param <V> value
*/
public final class DoubleHashingMap<K, V> implements Map<K, V> {
// Do not edit these 3 instance fields!!!
private K[] keys;
private V[] values;
private boolean[] removed;

/**
* Создает новый ассоциативный массив в соответствии с expectedMaxSize и loadFactor.
* Сразу выделяет начальное количество памяти на основе expectedMaxSize и loadFactor.
*
* @param expectedMaxSize ожидаемое максимальное количество элементов в ассоциативном массие.
* Это значит, что capacity - размер массивов под капотом -
* не будет увеличиваться до тех пор, пока количество элементов
* не станет больше чем expectedMaxSize
* @param loadFactor отношение количества элементов к размеру массивов
*/
public DoubleHashingMap(int expectedMaxSize, float loadFactor) {
keys = allocate(0);
values = allocate(0);
removed = new boolean[0];
}

@Override
public int size() {
throw new UnsupportedOperationException();
}

@Override
public boolean containsKey(K key) {
throw new UnsupportedOperationException();
}

@Nullable
@Override
public V get(K key) {
throw new UnsupportedOperationException();
}

/**
* Если capacity * loadFactor == size() и будет добавлен новый ключ,
* то нужно выполнить расширение массивов
*/
@Nullable
@Override
public V put(K key, V value) {
throw new UnsupportedOperationException();
}

@Nullable
@Override
public V remove(K key) {
throw new UnsupportedOperationException();
}

@Override
public void forEach(BiConsumer<K, V> consumer) {
throw new UnsupportedOperationException();
}

@SuppressWarnings("unchecked")
private static <T> T[] allocate(int capacity) {
return (T[]) new Object[capacity];
}
}
62 changes: 62 additions & 0 deletions src/main/java/company/vk/polis/ads/hash/Map.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package company.vk.polis.ads.hash;

import java.util.function.BiConsumer;

import org.jetbrains.annotations.Nullable;

/**
* Map aka Dictionary or Associative array
*
* @param <K> key
* @param <V> value
*/
public interface Map<K, V> {
int size();

default boolean isEmpty() {
return size() == 0;
}

/**
* Checks if key is present.
*
* @param key key
* @return true if key is present and false otherwise
*/
boolean containsKey(K key);

/**
* Returns value associated with key
*
* @param key key
* @return value associated with key
*/
@Nullable
V get(K key);

/**
* Puts key and value associated with it
*
* @param key key
* @param value value
* @return old value associated with key if one present or null otherwise
*/
@Nullable
V put(K key, V value);

/**
* Removes value associated with key
*
* @param key key
* @return value removed from map if one was or null otherwise
*/
@Nullable
V remove(K key);

/**
* Iterates over map and passes key-value pairs to consumer
*
* @param consumer object that consumes key-value pairs
*/
void forEach(BiConsumer<K, V> consumer);
}
85 changes: 85 additions & 0 deletions src/main/java/company/vk/polis/ads/hash/SeparateChainingMap.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package company.vk.polis.ads.hash;

import java.util.function.BiConsumer;

import org.jetbrains.annotations.Nullable;

/**
* Map implementation with separate chaining collision resolution approach
*
* @param <K> key
* @param <V> value
*/
public final class SeparateChainingMap<K, V> implements Map<K, V> {
// Do not edit this field!!!
private Node<K, V>[] array;

/**
* Создает новый ассоциативный массив в соответствии с expectedMaxSize и loadFactor.
* Сразу выделяет начальное количество памяти на основе expectedMaxSize и loadFactor.
*
* @param expectedMaxSize ожидаемое максимальное количество элементов в ассоциативном массие.
* Это значит, что capacity - размер массива связных списков -
* не будет увеличиваться до тех пор, пока количество элементов
* не станет больше чем expectedMaxSize
* @param loadFactor отношение количества элементов к размеру массива связных списков
*/
public SeparateChainingMap(int expectedMaxSize, float loadFactor) {
array = allocate(0);
throw new UnsupportedOperationException();
}

@Override
public int size() {
throw new UnsupportedOperationException();
}

@Override
public boolean containsKey(K key) {
throw new UnsupportedOperationException();
}

@Nullable
@Override
public V get(K key) {
throw new UnsupportedOperationException();
}

/**
* Если capacity * loadFactor == size() и будет добавлен новый ключ,
* то нужно выполнить расширение массивов
*/
@Nullable
@Override
public V put(K key, V value) {
throw new UnsupportedOperationException();
}

@Nullable
@Override
public V remove(K key) {
throw new UnsupportedOperationException();
}

@Override
public void forEach(BiConsumer<K, V> consumer) {
throw new UnsupportedOperationException();
}

@SuppressWarnings("unchecked")
private static <K, V> Node<K, V>[] allocate(int capacity) {
return (Node<K, V>[]) new Node[capacity];
}

private static final class Node<K, V> {
K key;
V value;
Node<K, V> prev;
Node<K, V> next;

Node(K key, V value) {
this.key = key;
this.value = value;
}
}
}
4 changes: 4 additions & 0 deletions src/main/java/company/vk/polis/ads/hash/package-info.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
@ParametersAreNonnullByDefault
package company.vk.polis.ads.hash;

import javax.annotation.ParametersAreNonnullByDefault;
53 changes: 53 additions & 0 deletions src/test/java/company/vk/polis/ads/hash/HashMapMapImpl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package company.vk.polis.ads.hash;

import java.util.HashMap;
import java.util.Objects;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;

import org.jetbrains.annotations.Nullable;

final class HashMapMapImpl<K, V> implements Map<K, V> {
private final java.util.Map<K, V> hashMap;

HashMapMapImpl(BiFunction<Integer, Float, java.util.Map<K, V>> m, int capacity, float loadFactor) {
hashMap = m.apply(capacity, loadFactor);
}

HashMapMapImpl(int capacity, float loadFactor) {
this(HashMap::new, capacity, loadFactor);
}

@Override
public int size() {
return hashMap.size();
}

@Override
public boolean containsKey(K key) {
return hashMap.containsKey(Objects.requireNonNull(key));
}

@Nullable
@Override
public V get(K key) {
return hashMap.get(Objects.requireNonNull(key));
}

@Nullable
@Override
public V put(K key, V value) {
return hashMap.put(Objects.requireNonNull(key), Objects.requireNonNull(value));
}

@Nullable
@Override
public V remove(K key) {
return hashMap.remove(Objects.requireNonNull(key));
}

@Override
public void forEach(BiConsumer<K, V> consumer) {
hashMap.forEach(consumer);
}
}
Loading

0 comments on commit 90e687c

Please sign in to comment.