1 /* 2 * This file is part of ELKI: 3 * Environment for Developing KDD-Applications Supported by Index-Structures 4 * 5 * Copyright (C) 2018 6 * ELKI Development Team 7 * 8 * This program is free software: you can redistribute it and/or modify 9 * it under the terms of the GNU Affero General Public License as published by 10 * the Free Software Foundation, either version 3 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU Affero General Public License for more details. 17 * 18 * You should have received a copy of the GNU Affero General Public License 19 * along with this program. If not, see <http://www.gnu.org/licenses/>. 20 */ 21 package de.lmu.ifi.dbs.elki.data; 22 23 import java.io.IOException; 24 import java.nio.ByteBuffer; 25 import java.util.Collection; 26 27 import de.lmu.ifi.dbs.elki.utilities.io.ByteArrayUtil; 28 import de.lmu.ifi.dbs.elki.utilities.io.ByteBufferSerializer; 29 import de.lmu.ifi.dbs.elki.utilities.io.FormatUtil; 30 31 /** 32 * A list of string labels. 33 * 34 * @author Erich Schubert 35 * @since 0.4.0 36 * 37 * @composed - - - String 38 */ 39 public class LabelList { 40 /** 41 * Serializer. 42 */ 43 public static final ByteBufferSerializer<LabelList> SERIALIZER = new Serializer(); 44 45 /** 46 * Labels. 47 */ 48 private String[] labels; 49 50 /** 51 * Empty label list. 52 */ 53 public static final LabelList EMPTY_LABELS = new LabelList(0); 54 55 /** 56 * Constructor. 57 * 58 * @param initialCapacity initial size 59 */ LabelList(int initialCapacity)60 private LabelList(int initialCapacity) { 61 super(); 62 labels = new String[initialCapacity]; 63 } 64 65 /** 66 * Private constructor. Use {@link #make}. 67 * 68 * @param array Label list 69 */ LabelList(String[] array)70 protected LabelList(String[] array) { 71 super(); 72 this.labels = array; 73 } 74 75 /** 76 * Constructor replacement. 77 * 78 * When the label list is empty, it will produce the same instance! 79 * 80 * @param labels Existing labels 81 * @return Label list instance. 82 */ make(Collection<String> labels)83 public static LabelList make(Collection<String> labels) { 84 int size = labels.size(); 85 if(size == 0) { 86 return EMPTY_LABELS; 87 } 88 return new LabelList(labels.toArray(new String[size])); 89 } 90 91 /** 92 * Size of label list. 93 * 94 * @return Size 95 */ size()96 public int size() { 97 return labels.length; 98 } 99 100 /** 101 * Get the label at position i. 102 * 103 * @param i Position 104 * @return Label 105 */ get(int i)106 public String get(int i) { 107 return labels[i]; 108 } 109 110 @Override toString()111 public String toString() { 112 return FormatUtil.format(labels, " "); 113 } 114 115 /** 116 * Serialization class. 117 * 118 * @author Erich Schubert 119 * 120 * @assoc - serializes - SimpleClassLabel 121 */ 122 public static class Serializer implements ByteBufferSerializer<LabelList> { 123 @Override fromByteBuffer(ByteBuffer buffer)124 public LabelList fromByteBuffer(ByteBuffer buffer) throws IOException { 125 final int cnt = ByteArrayUtil.readUnsignedVarint(buffer); 126 LabelList ret = new LabelList(cnt); 127 for(int i = 0; i < cnt; i++) { 128 ret.labels[i] = ByteArrayUtil.STRING_SERIALIZER.fromByteBuffer(buffer); 129 } 130 return ret; 131 } 132 133 @Override toByteBuffer(ByteBuffer buffer, LabelList object)134 public void toByteBuffer(ByteBuffer buffer, LabelList object) throws IOException { 135 final int cnt = object.labels.length; 136 ByteArrayUtil.writeUnsignedVarint(buffer, cnt); 137 for(int i = 0; i < cnt; i++) { 138 ByteArrayUtil.STRING_SERIALIZER.toByteBuffer(buffer, object.labels[i]); 139 } 140 } 141 142 @Override getByteSize(LabelList object)143 public int getByteSize(LabelList object) throws IOException { 144 final int cnt = object.labels.length; 145 int size = ByteArrayUtil.getUnsignedVarintSize(cnt); 146 for(int i = 0; i < cnt; i++) { 147 size += ByteArrayUtil.STRING_SERIALIZER.getByteSize(object.labels[i]); 148 } 149 return size; 150 } 151 } 152 } 153