Java tutorial
/* * The MIT License (MIT) * * Copyright (c) 2016. Diorite (by Bartomiej Mazur (aka GotoFinal)) * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package org.diorite.impl.world.chunk.palette; import java.lang.ref.SoftReference; import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; import org.diorite.impl.connection.packets.PacketDataSerializer; import org.diorite.material.BlockMaterialData; import org.diorite.utils.math.DioriteMathUtils; import it.unimi.dsi.fastutil.ints.Int2IntMap; import it.unimi.dsi.fastutil.ints.Int2IntMap.Entry; import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; public class MapPaletteImpl implements PaletteData { protected static final int GLOBAL_SIZE_DOWN = 4095; protected final Int2IntMap pattern; protected final Int2IntMap mirror; private int lastUsed = 0; public MapPaletteImpl() { this.pattern = new Int2IntOpenHashMap(64, .5F); this.pattern.defaultReturnValue(0); this.mirror = new Int2IntOpenHashMap(64, .5F); this.mirror.defaultReturnValue(-1); } private MapPaletteImpl(final Int2IntMap pattern, final Int2IntMap mirror, final int lastUsed) { this.pattern = new Int2IntOpenHashMap(pattern); this.mirror = new Int2IntOpenHashMap(mirror); this.lastUsed = lastUsed; } public MapPaletteImpl(final ArrayPaletteImpl old) { this.pattern = new Int2IntOpenHashMap(64, .5F); this.pattern.defaultReturnValue(0); this.mirror = new Int2IntOpenHashMap(64, .5F); this.mirror.defaultReturnValue(-1); for (final BlockMaterialData mat : old.pattern) { final int mcID = mat.getIdAndMeta(); this.pattern.put(this.lastUsed, mcID); this.mirror.put(mcID, this.lastUsed++); } } @Override public int bitsPerBlock() { final int size = this.lastUsed; if (size <= 1) { return 4; } return Math.max(4, Integer.SIZE - Integer.numberOfLeadingZeros(size - 1)); } @Override public int byteSize() { int bytes = DioriteMathUtils.varintSize(this.lastUsed); for (int i = 0; i < this.lastUsed; ++i) { bytes += DioriteMathUtils.varintSize(this.pattern.get(i)); } return bytes; } @Override public int put(final int minecraftIDandData) { if (this.pattern.containsValue(minecraftIDandData)) { return this.mirror.get(minecraftIDandData); } if (this.lastUsed >= GLOBAL_SIZE_DOWN) { return -1; } this.pattern.put(this.lastUsed, minecraftIDandData); return this.lastUsed++; } @Override public int getAsInt(final int sectionID) { return this.pattern.get(sectionID); } @Override public int size() { return this.lastUsed; } private transient SoftReference<int[]> ref; @Override public void write(final PacketDataSerializer data) { int[] mapping = (this.ref == null) ? null : this.ref.get(); if (mapping == null) { synchronized (this.pattern) { mapping = new int[this.pattern.size()]; for (final Entry entry : this.pattern.int2IntEntrySet()) { mapping[entry.getIntKey()] = entry.getIntValue(); } this.ref = new SoftReference<>(mapping); } } data.writeVarInt(mapping.length); for (final int i : mapping) { data.writeVarInt(i); } } @Override public void read(final PacketDataSerializer data) { final int size = data.readVarInt(); for (int i = 0; i < size; i++) { final int k = data.readVarInt(); this.pattern.put(i, k); this.mirror.put(k, i); this.lastUsed++; } } @Override public PaletteData getNext() { return GlobalPaletteImpl.get(); } @Override public PaletteData clone() { return new MapPaletteImpl(this.pattern, this.mirror, this.lastUsed); } // // for bits >13 // private static int lastSize = Material.getAllMaterialsCount(); // private static int[] mapping = null; // // @SuppressWarnings("SynchronizeOnNonFinalField") // private static void tryUpdateMapping() // { // if (mapping == null) // { // updateMapping(); // return; // } // synchronized (mapping) // { // if (lastSize != Material.getAllMaterialsCount()) // { // lastSize = Material.getAllMaterialsCount(); // updateMapping(); // } // } // } // // @SuppressWarnings("SynchronizeOnNonFinalField") // private static synchronized void updateMapping() // { // mapping = new int[Material.getAllMaterialsCount()]; // synchronized (mapping) // { // int i = 0; // for (final Material material : Material.values()) // { // if (! (material instanceof BlockMaterialData)) // { // continue; // } // final BlockMaterialData blockMat = (BlockMaterialData) material; // for (final BlockMaterialData data : blockMat.types()) // { // mapping[i++] = ((data.getId() << 4) | data.getType()); // } // } // } // } @Override public String toString() { return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE).appendSuper(super.toString()) .append("pattern", this.pattern).append("lastUsed", this.lastUsed).toString(); } }