-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
35a0d16
commit 54e8531
Showing
5 changed files
with
208 additions
and
62 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
67 changes: 67 additions & 0 deletions
67
src/main/scala/org/dbpedia/databus/CachingJsonldContext.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
package org.dbpedia.databus | ||
|
||
import java.util.concurrent.ConcurrentHashMap | ||
|
||
import com.github.jsonldjava.core.{Context, JsonLdOptions} | ||
import org.dbpedia.databus.CachingJsonldContext.ApproxSizeStringKeyCache | ||
|
||
import scala.collection.JavaConverters._ | ||
|
||
class CachingJsonldContext(sizeLimit: Int, opts: JsonLdOptions) extends Context(opts) { | ||
|
||
private val cache = new ApproxSizeStringKeyCache[Context](sizeLimit) | ||
|
||
override def parse(ctx: Object): Context = | ||
ctx match { | ||
case s: String => | ||
cache.get(s) | ||
.map(c => super.parse(c)) | ||
.getOrElse({ | ||
val re = super.parse(ctx) | ||
cache.put(s, re) | ||
re | ||
}) | ||
case _ => super.parse(ctx) | ||
} | ||
|
||
|
||
|
||
} | ||
|
||
object CachingJsonldContext { | ||
|
||
// not the most efficient impl, but should work for now :) | ||
class ApproxSizeStringKeyCache[T](sizeLimit: Int) { | ||
private val cache = new ConcurrentHashMap[StringCacheKey, T](sizeLimit) | ||
|
||
def put(s: String, c: T) = { | ||
// not trying to keep the size strictly equal to the limit | ||
cache.put(new StringCacheKey(s), c) | ||
if (cache.size() > sizeLimit) { | ||
keysSorted | ||
.take(cache.size() - sizeLimit) | ||
.foreach(cache.remove) | ||
} | ||
} | ||
|
||
def get(s: String): Option[T] = | ||
Option(cache.get(new StringCacheKey(s))) | ||
|
||
def keysSorted: Seq[StringCacheKey] = | ||
cache.keySet() | ||
.asScala.toSeq.sorted | ||
|
||
} | ||
|
||
class StringCacheKey(val str: String, val order: Long = System.nanoTime()) extends Comparable[StringCacheKey] { | ||
override def equals(other: Any): Boolean = other match { | ||
case that: StringCacheKey => that.str == this.str | ||
case _ => false | ||
} | ||
|
||
override def hashCode(): Int = str.hashCode | ||
|
||
override def compareTo(o: StringCacheKey): Int = this.order.compareTo(o.order) | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
package org.dbpedia.databus | ||
|
||
import java.util.UUID | ||
|
||
import org.dbpedia.databus.CachingJsonldContext.ApproxSizeStringKeyCache | ||
import org.scalatest.{FlatSpec, Matchers} | ||
|
||
class CacheTests extends FlatSpec with Matchers { | ||
|
||
"CacheKey" should "be sorted by time of creation" in { | ||
|
||
val caches = | ||
Seq( | ||
new CachingJsonldContext.StringCacheKey("scsc", 0), | ||
new CachingJsonldContext.StringCacheKey("scsc", -10), | ||
new CachingJsonldContext.StringCacheKey("scsc", 100), | ||
new CachingJsonldContext.StringCacheKey("zzzz", 0), | ||
new CachingJsonldContext.StringCacheKey("aaaa", 0) | ||
) | ||
|
||
caches.sorted.map(k => k.order) should contain theSameElementsInOrderAs (Seq(-10, 0, 0, 0, 100)) | ||
|
||
} | ||
|
||
"CacheKey" should "be equal with same string" in { | ||
val re = new CachingJsonldContext.StringCacheKey("scsc", 0) == new CachingJsonldContext.StringCacheKey("scsc", -10) | ||
re should be(true) | ||
|
||
val re2 = new CachingJsonldContext.StringCacheKey("scsc", 0) == new CachingJsonldContext.StringCacheKey("aaaa", 0) | ||
re2 should be(false) | ||
} | ||
|
||
"ApproxSizeCache" should "not overflow the size" in { | ||
val cache = new ApproxSizeStringKeyCache[Int](10) | ||
val seq = (1 to 100).map(i => (UUID.randomUUID().toString, i)) | ||
seq.foreach(p => cache.put(p._1, p._2)) | ||
|
||
cache.keysSorted.map(_.str) should contain theSameElementsInOrderAs (seq.drop(90).map(_._1)) | ||
} | ||
|
||
"ApproxSizeCache" should "have same size for same string key" in { | ||
val cache = new ApproxSizeStringKeyCache[Int](10) | ||
val seq = Seq("a", "a", "a") | ||
seq.foreach(p => cache.put(p, UUID.randomUUID().hashCode())) | ||
|
||
cache.keysSorted.size should be(1) | ||
} | ||
|
||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters