feat[set]: 添加性能更加高的原生基础类型的固定大小set

This commit is contained in:
godotg
2022-09-23 22:51:56 +08:00
parent 8783790724
commit e540fa13db
9 changed files with 911 additions and 1 deletions
@@ -0,0 +1,108 @@
/*
* Copyright (C) 2020 The zfoo Authors
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and limitations under the License.
*/
package com.zfoo.protocol.collection;
import java.util.AbstractSet;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Objects;
/**
* @author godotg
* @version 3.0
*/
public class FixedHashSet<E> extends AbstractSet<E> {
private final Object[] array;
private final boolean[] existArray;
public FixedHashSet(FixedSizeList<E> list) {
var length = list.size();
this.array = new Object[length];
this.existArray = new boolean[length];
var hashCollisionList = new ArrayList<E>();
for (var i = 0; i < length; i++) {
var ele = list.get(i);
var hash = Math.abs(Objects.hashCode(ele) % length);
if (existArray[hash]) {
hashCollisionList.add(ele);
} else {
array[hash] = ele;
existArray[hash] = true;
}
}
if (CollectionUtils.isNotEmpty(hashCollisionList)) {
for (int i = 0, j = 0; i < length; i++) {
if (hashCollisionList.size() == j) {
break;
}
if (existArray[i]) {
continue;
}
array[i] = hashCollisionList.get(j++);
existArray[i] = true;
}
}
}
@Override
public boolean contains(Object ele) {
var hash = Math.abs(Objects.hashCode(ele) % array.length);
if (array[hash] == ele && existArray[hash]) {
return true;
}
for (var i = 0; i < array.length; i++) {
if (array[i] == ele && existArray[i]) {
return true;
}
}
return false;
}
@Override
public int size() {
var length = 0;
for (var i = 0; i < array.length; i++) {
if (existArray[i]) {
length++;
}
}
return length;
}
@Override
public Iterator<E> iterator() {
var list = new ArrayList<E>();
for (var i = 0; i < array.length; i++) {
if (existArray[i]) {
list.add((E) array[i]);
}
}
return list.iterator();
}
@Override
public boolean add(E e) {
throw new UnsupportedOperationException();
}
@Override
public boolean remove(Object o) {
throw new UnsupportedOperationException();
}
@Override
public void clear() {
throw new UnsupportedOperationException();
}
}
@@ -0,0 +1,112 @@
/*
* Copyright (C) 2020 The zfoo Authors
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and limitations under the License.
*/
package com.zfoo.protocol.collection;
import java.util.AbstractSet;
import java.util.ArrayList;
import java.util.Iterator;
/**
* @author godotg
* @version 3.0
*/
public class FixedHashSetBoolean extends AbstractSet<Boolean> {
private final boolean[] array;
private final boolean[] existArray;
public FixedHashSetBoolean(FixedSizeListBoolean list) {
var length = list.size();
this.array = new boolean[length];
this.existArray = new boolean[length];
var hashCollisionList = new ArrayList<Boolean>();
for (var i = 0; i < length; i++) {
var ele = list.getRaw(i);
var hash = Boolean.hashCode(ele) % length;
if (existArray[hash]) {
hashCollisionList.add(ele);
} else {
array[hash] = ele;
existArray[hash] = true;
}
}
if (CollectionUtils.isNotEmpty(hashCollisionList)) {
for (int i = 0, j = 0; i < length; i++) {
if (hashCollisionList.size() == j) {
break;
}
if (existArray[i]) {
continue;
}
array[i] = hashCollisionList.get(j++);
existArray[i] = true;
}
}
}
@Override
public boolean contains(Object ele) {
var e = (Boolean) ele;
return contains(e.booleanValue());
}
public boolean contains(boolean ele) {
var hash = Boolean.hashCode(ele) % array.length;
if (array[hash] == ele && existArray[hash]) {
return true;
}
for (var i = 0; i < array.length; i++) {
if (array[i] == ele && existArray[i]) {
return true;
}
}
return false;
}
@Override
public int size() {
var length = 0;
for (var i = 0; i < array.length; i++) {
if (existArray[i]) {
length++;
}
}
return length;
}
@Override
public Iterator<Boolean> iterator() {
var list = new ArrayList<Boolean>();
for (var i = 0; i < array.length; i++) {
if (existArray[i]) {
list.add(array[i]);
}
}
return list.iterator();
}
@Override
public boolean add(Boolean e) {
throw new UnsupportedOperationException();
}
@Override
public boolean remove(Object o) {
throw new UnsupportedOperationException();
}
@Override
public void clear() {
throw new UnsupportedOperationException();
}
}
@@ -0,0 +1,112 @@
/*
* Copyright (C) 2020 The zfoo Authors
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and limitations under the License.
*/
package com.zfoo.protocol.collection;
import java.util.AbstractSet;
import java.util.ArrayList;
import java.util.Iterator;
/**
* @author godotg
* @version 3.0
*/
public class FixedHashSetByte extends AbstractSet<Byte> {
private final byte[] array;
private final boolean[] existArray;
public FixedHashSetByte(FixedSizeListByte list) {
var length = list.size();
this.array = new byte[length];
this.existArray = new boolean[length];
var hashCollisionList = new ArrayList<Byte>();
for (var i = 0; i < length; i++) {
var ele = list.getRaw(i);
var hash = Math.abs(ele % length);
if (existArray[hash]) {
hashCollisionList.add(ele);
} else {
array[hash] = ele;
existArray[hash] = true;
}
}
if (CollectionUtils.isNotEmpty(hashCollisionList)) {
for (int i = 0, j = 0; i < length; i++) {
if (hashCollisionList.size() == j) {
break;
}
if (existArray[i]) {
continue;
}
array[i] = hashCollisionList.get(j++);
existArray[i] = true;
}
}
}
@Override
public boolean contains(Object ele) {
var e = (Byte) ele;
return contains(e.byteValue());
}
public boolean contains(byte ele) {
var hash = Math.abs(ele % array.length);
if (array[hash] == ele && existArray[hash]) {
return true;
}
for (var i = 0; i < array.length; i++) {
if (array[i] == ele && existArray[i]) {
return true;
}
}
return false;
}
@Override
public int size() {
var length = 0;
for (var i = 0; i < array.length; i++) {
if (existArray[i]) {
length++;
}
}
return length;
}
@Override
public Iterator<Byte> iterator() {
var list = new ArrayList<Byte>();
for (var i = 0; i < array.length; i++) {
if (existArray[i]) {
list.add(array[i]);
}
}
return list.iterator();
}
@Override
public boolean add(Byte e) {
throw new UnsupportedOperationException();
}
@Override
public boolean remove(Object o) {
throw new UnsupportedOperationException();
}
@Override
public void clear() {
throw new UnsupportedOperationException();
}
}
@@ -0,0 +1,112 @@
/*
* Copyright (C) 2020 The zfoo Authors
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and limitations under the License.
*/
package com.zfoo.protocol.collection;
import java.util.AbstractSet;
import java.util.ArrayList;
import java.util.Iterator;
/**
* @author godotg
* @version 3.0
*/
public class FixedHashSetDouble extends AbstractSet<Double> {
private final double[] array;
private final boolean[] existArray;
public FixedHashSetDouble(FixedSizeListDouble list) {
var length = list.size();
this.array = new double[length];
this.existArray = new boolean[length];
var hashCollisionList = new ArrayList<Double>();
for (var i = 0; i < length; i++) {
var ele = list.getRaw(i);
var hash = Math.abs((int) ele % length);
if (existArray[hash]) {
hashCollisionList.add(ele);
} else {
array[hash] = ele;
existArray[hash] = true;
}
}
if (CollectionUtils.isNotEmpty(hashCollisionList)) {
for (int i = 0, j = 0; i < length; i++) {
if (hashCollisionList.size() == j) {
break;
}
if (existArray[i]) {
continue;
}
array[i] = hashCollisionList.get(j++);
existArray[i] = true;
}
}
}
@Override
public boolean contains(Object ele) {
var e = (Double) ele;
return contains(e.doubleValue());
}
public boolean contains(double ele) {
var hash = Math.abs((int) ele % array.length);
if (array[hash] == ele && existArray[hash]) {
return true;
}
for (var i = 0; i < array.length; i++) {
if (array[i] == ele && existArray[i]) {
return true;
}
}
return false;
}
@Override
public int size() {
var length = 0;
for (var i = 0; i < array.length; i++) {
if (existArray[i]) {
length++;
}
}
return length;
}
@Override
public Iterator<Double> iterator() {
var list = new ArrayList<Double>();
for (var i = 0; i < array.length; i++) {
if (existArray[i]) {
list.add(array[i]);
}
}
return list.iterator();
}
@Override
public boolean add(Double e) {
throw new UnsupportedOperationException();
}
@Override
public boolean remove(Object o) {
throw new UnsupportedOperationException();
}
@Override
public void clear() {
throw new UnsupportedOperationException();
}
}
@@ -0,0 +1,112 @@
/*
* Copyright (C) 2020 The zfoo Authors
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and limitations under the License.
*/
package com.zfoo.protocol.collection;
import java.util.AbstractSet;
import java.util.ArrayList;
import java.util.Iterator;
/**
* @author godotg
* @version 3.0
*/
public class FixedHashSetFloat extends AbstractSet<Float> {
private final float[] array;
private final boolean[] existArray;
public FixedHashSetFloat(FixedSizeListFloat list) {
var length = list.size();
this.array = new float[length];
this.existArray = new boolean[length];
var hashCollisionList = new ArrayList<Float>();
for (var i = 0; i < length; i++) {
var ele = list.getRaw(i);
var hash = Math.abs((int) ele % length);
if (existArray[hash]) {
hashCollisionList.add(ele);
} else {
array[hash] = ele;
existArray[hash] = true;
}
}
if (CollectionUtils.isNotEmpty(hashCollisionList)) {
for (int i = 0, j = 0; i < length; i++) {
if (hashCollisionList.size() == j) {
break;
}
if (existArray[i]) {
continue;
}
array[i] = hashCollisionList.get(j++);
existArray[i] = true;
}
}
}
@Override
public boolean contains(Object ele) {
var e = (Float) ele;
return contains(e.floatValue());
}
public boolean contains(float ele) {
var hash = Math.abs((int) ele % array.length);
if (array[hash] == ele && existArray[hash]) {
return true;
}
for (var i = 0; i < array.length; i++) {
if (array[i] == ele && existArray[i]) {
return true;
}
}
return false;
}
@Override
public int size() {
var length = 0;
for (var i = 0; i < array.length; i++) {
if (existArray[i]) {
length++;
}
}
return length;
}
@Override
public Iterator<Float> iterator() {
var list = new ArrayList<Float>();
for (var i = 0; i < array.length; i++) {
if (existArray[i]) {
list.add(array[i]);
}
}
return list.iterator();
}
@Override
public boolean add(Float e) {
throw new UnsupportedOperationException();
}
@Override
public boolean remove(Object o) {
throw new UnsupportedOperationException();
}
@Override
public void clear() {
throw new UnsupportedOperationException();
}
}
@@ -0,0 +1,112 @@
/*
* Copyright (C) 2020 The zfoo Authors
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and limitations under the License.
*/
package com.zfoo.protocol.collection;
import java.util.AbstractSet;
import java.util.ArrayList;
import java.util.Iterator;
/**
* @author godotg
* @version 3.0
*/
public class FixedHashSetInt extends AbstractSet<Integer> {
private final int[] array;
private final boolean[] existArray;
public FixedHashSetInt(FixedSizeListInt list) {
var length = list.size();
this.array = new int[length];
this.existArray = new boolean[length];
var hashCollisionList = new ArrayList<Integer>();
for (var i = 0; i < length; i++) {
var ele = list.getRaw(i);
var hash = Math.abs(ele % length);
if (existArray[hash]) {
hashCollisionList.add(ele);
} else {
array[hash] = ele;
existArray[hash] = true;
}
}
if (CollectionUtils.isNotEmpty(hashCollisionList)) {
for (int i = 0, j = 0; i < length; i++) {
if (hashCollisionList.size() == j) {
break;
}
if (existArray[i]) {
continue;
}
array[i] = hashCollisionList.get(j++);
existArray[i] = true;
}
}
}
@Override
public boolean contains(Object ele) {
var e = (Integer) ele;
return contains(e.intValue());
}
public boolean contains(int ele) {
var hash = Math.abs(ele % array.length);
if (array[hash] == ele && existArray[hash]) {
return true;
}
for (var i = 0; i < array.length; i++) {
if (array[i] == ele && existArray[i]) {
return true;
}
}
return false;
}
@Override
public int size() {
var length = 0;
for (var i = 0; i < array.length; i++) {
if (existArray[i]) {
length++;
}
}
return length;
}
@Override
public Iterator<Integer> iterator() {
var list = new ArrayList<Integer>();
for (var i = 0; i < array.length; i++) {
if (existArray[i]) {
list.add(array[i]);
}
}
return list.iterator();
}
@Override
public boolean add(Integer e) {
throw new UnsupportedOperationException();
}
@Override
public boolean remove(Object o) {
throw new UnsupportedOperationException();
}
@Override
public void clear() {
throw new UnsupportedOperationException();
}
}
@@ -0,0 +1,112 @@
/*
* Copyright (C) 2020 The zfoo Authors
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and limitations under the License.
*/
package com.zfoo.protocol.collection;
import java.util.AbstractSet;
import java.util.ArrayList;
import java.util.Iterator;
/**
* @author godotg
* @version 3.0
*/
public class FixedHashSetLong extends AbstractSet<Long> {
private final long[] array;
private final boolean[] existArray;
public FixedHashSetLong(FixedSizeListLong list) {
var length = list.size();
this.array = new long[length];
this.existArray = new boolean[length];
var hashCollisionList = new ArrayList<Long>();
for (var i = 0; i < length; i++) {
var ele = list.getRaw(i);
var hash = Math.abs((int) ele % length);
if (existArray[hash]) {
hashCollisionList.add(ele);
} else {
array[hash] = ele;
existArray[hash] = true;
}
}
if (CollectionUtils.isNotEmpty(hashCollisionList)) {
for (int i = 0, j = 0; i < length; i++) {
if (hashCollisionList.size() == j) {
break;
}
if (existArray[i]) {
continue;
}
array[i] = hashCollisionList.get(j++);
existArray[i] = true;
}
}
}
@Override
public boolean contains(Object ele) {
var e = (Long) ele;
return contains(e.intValue());
}
public boolean contains(long ele) {
var hash = Math.abs((int) ele % array.length);
if (array[hash] == ele && existArray[hash]) {
return true;
}
for (var i = 0; i < array.length; i++) {
if (array[i] == ele && existArray[i]) {
return true;
}
}
return false;
}
@Override
public int size() {
var length = 0;
for (var i = 0; i < array.length; i++) {
if (existArray[i]) {
length++;
}
}
return length;
}
@Override
public Iterator<Long> iterator() {
var list = new ArrayList<Long>();
for (var i = 0; i < array.length; i++) {
if (existArray[i]) {
list.add(array[i]);
}
}
return list.iterator();
}
@Override
public boolean add(Long e) {
throw new UnsupportedOperationException();
}
@Override
public boolean remove(Object o) {
throw new UnsupportedOperationException();
}
@Override
public void clear() {
throw new UnsupportedOperationException();
}
}
@@ -0,0 +1,112 @@
/*
* Copyright (C) 2020 The zfoo Authors
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and limitations under the License.
*/
package com.zfoo.protocol.collection;
import java.util.AbstractSet;
import java.util.ArrayList;
import java.util.Iterator;
/**
* @author godotg
* @version 3.0
*/
public class FixedHashSetShort extends AbstractSet<Short> {
private final short[] array;
private final boolean[] existArray;
public FixedHashSetShort(FixedSizeListShort list) {
var length = list.size();
this.array = new short[length];
this.existArray = new boolean[length];
var hashCollisionList = new ArrayList<Short>();
for (var i = 0; i < length; i++) {
var ele = list.getRaw(i);
var hash = Math.abs(ele % length);
if (existArray[hash]) {
hashCollisionList.add(ele);
} else {
array[hash] = ele;
existArray[hash] = true;
}
}
if (CollectionUtils.isNotEmpty(hashCollisionList)) {
for (int i = 0, j = 0; i < length; i++) {
if (hashCollisionList.size() == j) {
break;
}
if (existArray[i]) {
continue;
}
array[i] = hashCollisionList.get(j++);
existArray[i] = true;
}
}
}
@Override
public boolean contains(Object ele) {
var e = (Short) ele;
return contains(e.shortValue());
}
public boolean contains(short ele) {
var hash = Math.abs(ele % array.length);
if (array[hash] == ele && existArray[hash]) {
return true;
}
for (var i = 0; i < array.length; i++) {
if (array[i] == ele && existArray[i]) {
return true;
}
}
return false;
}
@Override
public int size() {
var length = 0;
for (var i = 0; i < array.length; i++) {
if (existArray[i]) {
length++;
}
}
return length;
}
@Override
public Iterator<Short> iterator() {
var list = new ArrayList<Short>();
for (var i = 0; i < array.length; i++) {
if (existArray[i]) {
list.add(array[i]);
}
}
return list.iterator();
}
@Override
public boolean add(Short e) {
throw new UnsupportedOperationException();
}
@Override
public boolean remove(Object o) {
throw new UnsupportedOperationException();
}
@Override
public void clear() {
throw new UnsupportedOperationException();
}
}
@@ -12,13 +12,14 @@
package com.zfoo.protocol.collection;
import org.junit.Assert;
import org.junit.Test;
/**
* @author godotg
* @version 3.0
*/
public class ListTest {
public class FixedCollectionTest {
@Test
public void testFixedSizeListInt() {
@@ -46,4 +47,21 @@ public class ListTest {
}
}
@Test
public void testFixedHashInt() {
var list = new FixedSizeListInt(3);
list.set(0, 1);
list.set(1, 2);
list.set(2, 4);
var set = new FixedHashSetInt(list);
for (int i = 0; i < set.size(); i++) {
for (var ele : set) {
// test iterator
}
}
Assert.assertTrue(set.contains(4));
}
}