RFR 4641897: Faster string conversion of large integers (original) (raw)

Aleksey Shipilev aleksey.shipilev at oracle.com
Sat Jun 22 10:50:26 UTC 2013


On 06/22/2013 08:06 AM, Dmitry Nadezhin wrote:

Alexey,

Each possible radix has its cacheLine in the cache. Cache contents looks like BigInteger[][] powerCache = new BigInteger[37] { /0/ null, /1/ null, /2/ new BigInteger[] { 2, 4, 16, 256, 32768, ... }, /3/ new BigInteger[] { 3, 9, 81, ... }, /4/ new BigInteger[] { 4, 16, 256, ... } /5/ new BigInteger[] { 5, 25, 625, ... }, /6/ new BigInteger[] { 6 }, /7/ new BigInteger[] { 7 }, . . . /36/ new BigInteger[] { 36 } }; Is there an idiom for a list/array of volatile references ?

AtomicReferenceArray is your friend there. Although I'm not sure why you need the list of volatile references in this case. Placing volatile to the root reference resolves the race.

I am not sure that such naive code works: volatile BigInteger[][] powerCache = ..,

Why wouldn't it work?

volatile T[][] cache;

T[] get(int index) { T[][] lc = cache; if (index >= lc.length) { // need resizing lc = generateNew(index << 1); cache = lc; } return lc[index]; }

If you need to populate the 2nd level, then you have to have the final volatile write to the cache.Thecorrespondingcache. The corresponding cache.Thecorrespondingcache volatile read makes the update on 2nd level visible.

T get(int index1, index2) { T[][] lc = cache; if (index1 >= lc.length) { // needs resizing lc = generateNewT2(index1 << 1); cache = lc; } T[] lt = lc[index2]; if (index2 >= lt.length) { // needs resizing lt = generateNewT1(index2 << 1); lc[index2] = lt; cache = lc; // publish } return lt[index2]; }

-Aleksey.



More information about the core-libs-dev mailing list