Skip to content
This repository was archived by the owner on Apr 22, 2020. It is now read-only.

Commit 400d568

Browse files
committed
Copy SimpleBitSet into project
1 parent a9b06b2 commit 400d568

File tree

3 files changed

+214
-90
lines changed

3 files changed

+214
-90
lines changed

algo/src/main/java/org/neo4j/graphalgo/impl/ShortestPathDijkstra.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@
66
import org.neo4j.graphalgo.core.utils.ProgressLogger;
77
import org.neo4j.graphalgo.core.utils.queue.IntPriorityQueue;
88
import org.neo4j.graphalgo.core.utils.queue.SharedIntMinPriorityQueue;
9+
import org.neo4j.graphalgo.core.utils.traverse.SimpleBitSet;
910
import org.neo4j.graphdb.Direction;
1011
import org.neo4j.kernel.api.exceptions.EntityNotFoundException;
1112
import org.neo4j.kernel.api.exceptions.InvalidTransactionTypeKernelException;
1213
import org.neo4j.kernel.api.exceptions.legacyindex.AutoIndexingKernelException;
1314
import org.neo4j.kernel.api.exceptions.schema.ConstraintValidationException;
1415
import org.neo4j.kernel.api.properties.DefinedProperty;
15-
import org.neo4j.kernel.impl.util.collection.SimpleBitSet;
1616
import org.neo4j.kernel.internal.GraphDatabaseAPI;
1717

1818
import java.util.stream.Stream;

core/src/main/java/org/neo4j/graphalgo/core/utils/traverse/SequentialTraverse.java

Lines changed: 0 additions & 89 deletions
This file was deleted.
Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
package org.neo4j.graphalgo.core.utils.traverse;
2+
3+
/*
4+
* Copyright (c) 2002-2017 "Neo Technology,"
5+
* Network Engine for Objects in Lund AB [http://neotechnology.com]
6+
*
7+
* This file is part of Neo4j.
8+
*
9+
* Neo4j is free software: you can redistribute it and/or modify
10+
* it under the terms of the GNU General Public License as published by
11+
* the Free Software Foundation, either version 3 of the License, or
12+
* (at your option) any later version.
13+
*
14+
* This program is distributed in the hope that it will be useful,
15+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+
* GNU General Public License for more details.
18+
*
19+
* You should have received a copy of the GNU General Public License
20+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
21+
*/
22+
23+
import org.neo4j.collection.primitive.PrimitiveIntIterable;
24+
import org.neo4j.collection.primitive.PrimitiveIntIterator;
25+
26+
import java.util.Arrays;
27+
import java.util.concurrent.locks.StampedLock;
28+
29+
/**
30+
* A basic bitset.
31+
* <p>
32+
* Represented using an automatically expanding long array, with one bit per key.
33+
* <p>
34+
* Performance:
35+
* * put, remove, contains, size: O(1)
36+
* * clear: O(size/64)
37+
* <p>
38+
* Concurrency semantics:
39+
* * Concurrent writes synchronise and is thread-safe
40+
* * Concurrent reads are thread-safe and will not observe torn writes, but may become
41+
* out of date as soon as the operation returns
42+
* * Concurrent reads during write is thread-safe
43+
* * Bulk operations appear atomic to concurrent readers
44+
* * Only caveat being that the iterator is not thread-safe
45+
*/
46+
public class SimpleBitSet extends StampedLock implements PrimitiveIntIterable
47+
{
48+
private long lastCheckPointKey;
49+
private long[] data;
50+
51+
public SimpleBitSet( int size )
52+
{
53+
int initialCapacity = size / 64;
54+
int capacity = 1;
55+
while ( capacity < initialCapacity )
56+
{
57+
capacity <<= 1;
58+
}
59+
long stamp = writeLock();
60+
data = new long[capacity];
61+
unlockWrite( stamp );
62+
}
63+
64+
public boolean contains( int key )
65+
{
66+
int idx = key >>> 6;
67+
boolean result;
68+
long stamp;
69+
do
70+
{
71+
stamp = tryOptimisticRead();
72+
result = data.length > idx && (data[idx] & ((1L << (key & 63)))) != 0;
73+
}
74+
while ( !validate( stamp ) );
75+
return result;
76+
}
77+
78+
public void put( int key )
79+
{
80+
long stamp = writeLock();
81+
int idx = key >>> 6;
82+
ensureCapacity( idx );
83+
data[idx] = data[idx] | (1L << (key & 63));
84+
unlockWrite( stamp );
85+
}
86+
87+
public void put( SimpleBitSet other )
88+
{
89+
long stamp = writeLock();
90+
ensureCapacity( other.data.length - 1 );
91+
for ( int i = 0; i < data.length && i < other.data.length; i++ )
92+
{
93+
data[i] = data[i] | other.data[i];
94+
}
95+
unlockWrite( stamp );
96+
}
97+
98+
public void clear( )
99+
{
100+
long stamp = writeLock();
101+
Arrays.fill( data, 0L);
102+
unlockWrite( stamp );
103+
}
104+
105+
public void remove( int key )
106+
{
107+
long stamp = writeLock();
108+
int idx = key >>> 6;
109+
if ( data.length > idx )
110+
{
111+
data[idx] = data[idx] & ~(1L << (key & 63));
112+
}
113+
unlockWrite( stamp );
114+
}
115+
116+
public void remove( SimpleBitSet other )
117+
{
118+
long stamp = writeLock();
119+
for ( int i = 0; i < data.length; i++ )
120+
{
121+
data[i] = data[i] & ~other.data[i];
122+
}
123+
unlockWrite( stamp );
124+
}
125+
126+
public long checkPointAndPut( long checkPoint, int key )
127+
{
128+
// We only need to clear the bit set if it was modified since the last check point
129+
if ( !validate( checkPoint ) || key != lastCheckPointKey )
130+
{
131+
long stamp = writeLock();
132+
int idx = key >>> 6;
133+
if ( idx < data.length )
134+
{
135+
Arrays.fill( data, 0 );
136+
}
137+
else
138+
{
139+
int len = data.length;
140+
len = findNewLength( idx, len );
141+
data = new long[len];
142+
}
143+
data[idx] = data[idx] | (1L << (key & 63));
144+
lastCheckPointKey = key;
145+
checkPoint = tryConvertToOptimisticRead( stamp );
146+
}
147+
return checkPoint;
148+
}
149+
150+
private int findNewLength( int idx, int len )
151+
{
152+
while ( len <= idx )
153+
{
154+
len *= 2;
155+
}
156+
return len;
157+
}
158+
159+
public int size()
160+
{
161+
int size = 0;
162+
for ( int i = 0; i < data.length; i++ )
163+
{
164+
size += Long.bitCount( data[i] );
165+
}
166+
return size;
167+
}
168+
169+
private void ensureCapacity( int arrayIndex )
170+
{
171+
data = Arrays.copyOf( data, findNewLength( arrayIndex, data.length ) );
172+
}
173+
174+
//
175+
// Views
176+
//
177+
178+
@Override
179+
public PrimitiveIntIterator iterator()
180+
{
181+
return new PrimitiveIntIterator()
182+
{
183+
private int next = 0;
184+
private final int size = data.length * 64;
185+
186+
{
187+
// Prefetch first
188+
while ( next < size && !contains( next ) )
189+
{
190+
next++;
191+
}
192+
}
193+
194+
@Override
195+
public boolean hasNext()
196+
{
197+
return next < size;
198+
}
199+
200+
@Override
201+
public int next()
202+
{
203+
int current = next;
204+
next++;
205+
while ( next < size && !contains( next ) )
206+
{
207+
next++;
208+
}
209+
return current;
210+
}
211+
};
212+
}
213+
}

0 commit comments

Comments
 (0)