001/*
002 * Copyright 2013 Alex Kasko (alexkasko.com)
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package com.alexkasko.unsafe.offheap;
018
019import com.alexkasko.unsafe.bytearray.ByteArrayTool;
020
021import java.util.concurrent.atomic.AtomicBoolean;
022
023/**
024 * Implementation of {@link com.alexkasko.unsafe.offheap.OffHeapMemory}
025 * using byte array effectively making it <b>OnHeap</b> memory
026 *
027 * @author alexkasko
028 * Date: 1/14/13
029*/
030class OnHeapMemory extends OffHeapMemory {
031
032    private final ByteArrayTool bt;
033    private byte[] mem;
034    private final AtomicBoolean disposed = new AtomicBoolean(false);
035
036    OnHeapMemory(ByteArrayTool bt, long bytes) {
037        if(bytes > Integer.MAX_VALUE) throw new IllegalArgumentException(
038                "Long-sized allocations are not supported by [" + getClass().getName() + "]");
039        this.bt = bt;
040        this.mem = new byte[(int) bytes];
041    }
042
043    /**
044     * {@inheritDoc}
045     */
046    @Override
047    public boolean isUnsafe() {
048        return false;
049    }
050
051    /**
052     * {@inheritDoc}
053     */
054    @Override
055    public long length() {
056        return mem.length;
057    }
058
059    /**
060     * {@inheritDoc}
061     */
062    @Override
063    public void free() {
064        if(!disposed.compareAndSet(false, true)) return;
065        this.mem = null;
066    }
067
068    /**
069     * {@inheritDoc}
070     */
071    @Override
072    public void put(long offset, byte[] buffer, int bufferOffset, int bytes) {
073        bt.copy(buffer, bufferOffset, mem, (int) offset, bytes);
074    }
075
076    /**
077     * {@inheritDoc}
078     */
079    @Override
080    public void put(long offset, byte[] buffer) {
081        bt.copy(buffer, 0, mem, (int) offset, buffer.length);
082    }
083
084    /**
085     * {@inheritDoc}
086     */
087    @Override
088    public void get(long offset, byte[] buffer, int bufferOffset, int bytes) {
089        bt.copy(mem, (int) offset, buffer, bufferOffset, bytes);
090    }
091
092    /**
093     * {@inheritDoc}
094     */
095    @Override
096    public void get(long offset, byte[] buffer) {
097        bt.copy(mem, (int) offset, buffer, 0, buffer.length);
098    }
099
100    /**
101     * {@inheritDoc}
102     */
103    @Override
104    public byte getByte(long offset) {
105        return bt.getByte(mem, (int) offset);
106    }
107
108    /**
109     * {@inheritDoc}
110     */
111    @Override
112    public void putByte(long offset, byte value) {
113        bt.putByte(mem, (int) offset, value);
114    }
115
116    /**
117     * {@inheritDoc}
118     */
119    @Override
120    public short getUnsignedByte(long offset) {
121        return bt.getUnsignedByte(mem, (int) offset);
122    }
123
124    /**
125     * {@inheritDoc}
126     */
127    @Override
128    public void putUnsignedByte(long offset, short value) {
129        bt.putUnsignedByte(mem, (int) offset, value);
130    }
131
132    /**
133     * {@inheritDoc}
134     */
135    @Override
136    public short getShort(long offset) {
137        return bt.getShort(mem, (int) offset);
138    }
139
140    /**
141     * {@inheritDoc}
142     */
143    @Override
144    public void putShort(long offset, short value) {
145        bt.putShort(mem, (int) offset, value);
146    }
147
148    /**
149     * {@inheritDoc}
150     */
151    @Override
152    public int getUnsignedShort(long offset) {
153        return bt.getUnsignedShort(mem, (int) offset);
154    }
155
156    /**
157     * {@inheritDoc}
158     */
159    @Override
160    public void putUnsignedShort(long offset, int value) {
161        bt.putUnsignedShort(mem, (int) offset, value);
162    }
163
164    /**
165     * {@inheritDoc}
166     */
167    @Override
168    public int getInt(long offset) {
169        return bt.getInt(mem, (int) offset);
170    }
171
172    /**
173     * {@inheritDoc}
174     */
175    @Override
176    public void putInt(long offset, int value) {
177        bt.putInt(mem, (int) offset, value);
178    }
179
180    /**
181     * {@inheritDoc}
182     */
183    @Override
184    public long getUnsignedInt(long offset) {
185        return bt.getUnsignedInt(mem, (int) offset);
186    }
187
188    /**
189     * {@inheritDoc}
190     */
191    @Override
192    public void putUnsignedInt(long offset, long value) {
193        bt.putUnsignedInt(mem, (int) offset, value);
194    }
195
196    /**
197     * {@inheritDoc}
198     */
199    @Override
200    public long getLong(long offset) {
201        return bt.getLong(mem, (int) offset);
202    }
203
204    /**
205     * {@inheritDoc}
206     */
207    @Override
208    public void putLong(long offset, long value) {
209        bt.putLong(mem, (int) offset, value);
210    }
211
212    /**
213     * {@inheritDoc}
214     */
215    @Override
216    public void copy(long offset, OffHeapMemory destination, long destOffset, long bytes) {
217        OnHeapMemory dest = (OnHeapMemory) destination;
218        bt.copy(mem, (int) offset, dest.mem, (int) destOffset, (int) bytes);
219    }
220
221    /**
222     * {@inheritDoc}
223     */
224    @Override
225    public OffHeapMemory clone() {
226        OnHeapMemory res = new OnHeapMemory(bt, mem.length);
227        this.copy(0, res, 0, mem.length);
228        return res;
229    }
230
231    /**
232     * {@inheritDoc}
233     */
234    @Override
235    public String toString() {
236        final StringBuilder sb = new StringBuilder();
237        sb.append("OnHeapMemory");
238        sb.append("{bt=").append(bt);
239        sb.append(", length=").append(!disposed.get() ? mem.length : -1);
240        sb.append(", disposed=").append(disposed);
241        sb.append('}');
242        return sb.toString();
243    }
244}