1 /*
2 * Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package jdk.tools.jlink.internal;
27
28 import java.nio.ByteOrder;
29 import java.util.ArrayList;
30 import java.util.List;
31 import java.util.Objects;
32 import jdk.internal.jimage.ImageHeader;
33 import jdk.internal.jimage.ImageStream;
34 import jdk.internal.jimage.ImageStringsReader;
35
36 public final class BasicImageWriter {
37 public static final String MODULES_IMAGE_NAME = "modules";
38
39 private ByteOrder byteOrder;
40 private ImageStringsWriter strings;
41 private int length;
42 private int[] redirect;
43 private ImageLocationWriter[] locations;
44 private List<ImageLocationWriter> input;
45 private ImageStream headerStream;
46 private ImageStream redirectStream;
47 private ImageStream locationOffsetStream;
48 private ImageStream locationStream;
49 private ImageStream allIndexStream;
50
51 public BasicImageWriter() {
52 this(ByteOrder.nativeOrder());
53 }
54
55 public BasicImageWriter(ByteOrder byteOrder) {
56 this.byteOrder = Objects.requireNonNull(byteOrder);
57 this.input = new ArrayList<>();
58 this.strings = new ImageStringsWriter();
59 this.headerStream = new ImageStream(byteOrder);
60 this.redirectStream = new ImageStream(byteOrder);
61 this.locationOffsetStream = new ImageStream(byteOrder);
62 this.locationStream = new ImageStream(byteOrder);
63 this.allIndexStream = new ImageStream(byteOrder);
64 }
65
66 public ByteOrder getByteOrder() {
67 return byteOrder;
68 }
69
70 public int addString(String string) {
71 return strings.add(string);
72 }
73
74 public String getString(int offset) {
75 return strings.get(offset);
76 }
77
78 public void addLocation(String fullname, long contentOffset,
79 long compressedSize, long uncompressedSize) {
80 ImageLocationWriter location =
81 ImageLocationWriter.newLocation(fullname, strings,
82 contentOffset, compressedSize, uncompressedSize);
83 input.add(location);
84 length++;
85 }
86
87 ImageLocationWriter[] getLocations() {
88 return locations;
89 }
90
91 int getLocationsCount() {
92 return input.size();
93 }
94
95 private void generatePerfectHash() {
96 PerfectHashBuilder<ImageLocationWriter> builder =
97 new PerfectHashBuilder<>(
98 PerfectHashBuilder.Entry.class,
99 PerfectHashBuilder.Bucket.class);
100
101 input.forEach((location) -> {
102 builder.put(location.getFullName(), location);
103 });
104
105 builder.generate();
106
107 length = builder.getCount();
108 redirect = builder.getRedirect();
109 PerfectHashBuilder.Entry<ImageLocationWriter>[] order = builder.getOrder();
110 locations = new ImageLocationWriter[length];
111
112 for (int i = 0; i < length; i++) {
113 locations[i] = order[i].getValue();
114 }
157 allIndexStream.put(headerStream);
158 allIndexStream.put(redirectStream);
159 allIndexStream.put(locationOffsetStream);
160 allIndexStream.put(locationStream);
161 allIndexStream.put(strings.getStream());
162 }
163
164 public byte[] getBytes() {
165 if (allIndexStream.getSize() == 0) {
166 generatePerfectHash();
167 prepareStringBytes();
168 prepareRedirectBytes();
169 prepareLocationBytes();
170 prepareOffsetBytes();
171 prepareHeaderBytes();
172 prepareTableBytes();
173 }
174
175 return allIndexStream.toArray();
176 }
177
178 ImageLocationWriter find(String key) {
179 int index = redirect[ImageStringsReader.hashCode(key) % length];
180
181 if (index < 0) {
182 index = -index - 1;
183 } else {
184 index = ImageStringsReader.hashCode(key, index) % length;
185 }
186
187 return locations[index];
188 }
189 }
|
1 /*
2 * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package jdk.tools.jlink.internal;
27
28 import java.nio.ByteOrder;
29 import java.util.ArrayList;
30 import java.util.List;
31 import java.util.Objects;
32 import jdk.internal.jimage.ImageHeader;
33 import jdk.internal.jimage.ImageStream;
34 import jdk.internal.jimage.ImageStringsReader;
35
36 public final class BasicImageWriter {
37 public static final String MODULES_IMAGE_NAME = "modules";
38
39 private final ByteOrder byteOrder;
40 private final ImageStringsWriter strings;
41 private int length;
42 private int[] redirect;
43 private ImageLocationWriter[] locations;
44 private final List<ImageLocationWriter> input;
45 private final ImageStream headerStream;
46 private final ImageStream redirectStream;
47 private final ImageStream locationOffsetStream;
48 private final ImageStream locationStream;
49 private final ImageStream allIndexStream;
50
51 public BasicImageWriter(ByteOrder byteOrder) {
52 this.byteOrder = Objects.requireNonNull(byteOrder);
53 this.input = new ArrayList<>();
54 this.strings = new ImageStringsWriter();
55 this.headerStream = new ImageStream(byteOrder);
56 this.redirectStream = new ImageStream(byteOrder);
57 this.locationOffsetStream = new ImageStream(byteOrder);
58 this.locationStream = new ImageStream(byteOrder);
59 this.allIndexStream = new ImageStream(byteOrder);
60 }
61
62 public ByteOrder getByteOrder() {
63 return byteOrder;
64 }
65
66 public int addString(String string) {
67 return strings.add(string);
68 }
69
70 public String getString(int offset) {
71 return strings.get(offset);
72 }
73
74 public void addLocation(
75 String fullname,
76 long contentOffset,
77 long compressedSize,
78 long uncompressedSize,
79 int previewFlags) {
80 ImageLocationWriter location =
81 ImageLocationWriter.newLocation(fullname, strings,
82 contentOffset, compressedSize, uncompressedSize, previewFlags);
83 input.add(location);
84 length++;
85 }
86
87 ImageLocationWriter[] getLocations() {
88 return locations;
89 }
90
91 private void generatePerfectHash() {
92 PerfectHashBuilder<ImageLocationWriter> builder =
93 new PerfectHashBuilder<>(
94 PerfectHashBuilder.Entry.class,
95 PerfectHashBuilder.Bucket.class);
96
97 input.forEach((location) -> {
98 builder.put(location.getFullName(), location);
99 });
100
101 builder.generate();
102
103 length = builder.getCount();
104 redirect = builder.getRedirect();
105 PerfectHashBuilder.Entry<ImageLocationWriter>[] order = builder.getOrder();
106 locations = new ImageLocationWriter[length];
107
108 for (int i = 0; i < length; i++) {
109 locations[i] = order[i].getValue();
110 }
153 allIndexStream.put(headerStream);
154 allIndexStream.put(redirectStream);
155 allIndexStream.put(locationOffsetStream);
156 allIndexStream.put(locationStream);
157 allIndexStream.put(strings.getStream());
158 }
159
160 public byte[] getBytes() {
161 if (allIndexStream.getSize() == 0) {
162 generatePerfectHash();
163 prepareStringBytes();
164 prepareRedirectBytes();
165 prepareLocationBytes();
166 prepareOffsetBytes();
167 prepareHeaderBytes();
168 prepareTableBytes();
169 }
170
171 return allIndexStream.toArray();
172 }
173 }
|