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.offheaplong; 018 019import com.alexkasko.unsafe.offheap.OffHeapDisposable; 020import com.alexkasko.unsafe.offheap.OffHeapDisposableIterator; 021import com.alexkasko.unsafe.offheap.OffHeapMemory; 022 023/** 024 * <p>Implementation of array of long using {@link com.alexkasko.unsafe.offheap.OffHeapMemory}. 025 * 026 * <p>Default implementation uses {@code sun.misc.Unsafe}, with all operations guarded with {@code assert} keyword. 027 * With assertions enabled in runtime ({@code -ea} java switch) {@link AssertionError} 028 * will be thrown on illegal index access. Without assertions illegal index will crash JVM. 029 * 030 * <p>Array won't be zeroed after creation (will contain garbage by default). 031 * Allocated memory may be freed manually using {@link #free()} (thread-safe 032 * and may be called multiple times) or it will be freed after {@link OffHeapLongArray} 033 * will be garbage collected. 034 * 035 * <p>Note: while class implements Iterable, iterator will create new autoboxed Long object 036 * <b>on every</b> {@code next()} call, this behaviour is inevitable with iterators in java 6/7. 037 * 038 * @author alexkasko 039 * Date: 2/22/13 040 */ 041public class OffHeapLongArray implements OffHeapLongAddressable, OffHeapDisposable, Iterable<Long> { 042 private static final int ELEMENT_LENGTH = 8; 043 044 private final OffHeapMemory ohm; 045 046 /** 047 * Constructor 048 * 049 * @param size number of elements in array 050 */ 051 public OffHeapLongArray(long size) { 052 this.ohm = OffHeapMemory.allocateMemory(size * ELEMENT_LENGTH); 053 } 054 055 /** 056 * Private constructor for {@link #clone()} support 057 * 058 * @param ohm cloned memory instance 059 */ 060 private OffHeapLongArray(OffHeapMemory ohm) { 061 this.ohm = ohm; 062 } 063 064 /** 065 * Whether unsafe implementation of {@link OffHeapMemory} is used 066 * 067 * @return whether unsafe implementation of {@link OffHeapMemory} is used 068 */ 069 public boolean isUnsafe() { 070 return ohm.isUnsafe(); 071 } 072 073 /** 074 * Gets the element at position {@code index} 075 * 076 * @param index array index 077 * @return long value 078 */ 079 @Override 080 public long get(long index) { 081 return ohm.getLong(index * ELEMENT_LENGTH); 082 } 083 084 /** 085 * Sets the element at position {@code index} to the given value 086 * 087 * @param index array index 088 * @param value long value 089 */ 090 @Override 091 public void set(long index, long value) { 092 ohm.putLong(index * ELEMENT_LENGTH, value); 093 } 094 095 /** 096 * Returns number of elements in array 097 * 098 * @return number of elements in array 099 */ 100 @Override 101 public long size() { 102 return ohm.length() / ELEMENT_LENGTH; 103 } 104 105 /** 106 * Frees allocated memory, may be called multiple times from any thread 107 */ 108 public void free() { 109 ohm.free(); 110 } 111 112 /** 113 * {@inheritDoc} 114 */ 115 @Override 116 public OffHeapDisposableIterator<Long> iterator() { 117 return new OffHeapLongIterator(this); 118 } 119 120 /** 121 * {@inheritDoc} 122 */ 123 @Override 124 public OffHeapLongArray clone() { 125 OffHeapMemory cloned = ohm.clone(); 126 return new OffHeapLongArray(cloned); 127 } 128 129 /** 130 * {@inheritDoc} 131 */ 132 @Override 133 public String toString() { 134 final StringBuilder sb = new StringBuilder(); 135 sb.append("OffHeapLongArray"); 136 sb.append("{size=").append(size()); 137 sb.append(", unsafe=").append(isUnsafe()); 138 sb.append('}'); 139 return sb.toString(); 140 } 141}