< prev index next >
src/java.security.jgss/share/classes/sun/security/krb5/internal/rcache/AuthList.java
Print this page
rev 48894 : 8197518: Kerberos krb5 authentication: AuthList's put method leads to performance issue
*** 1,7 ****
/*
! * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
--- 1,7 ----
/*
! * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
*** 53,62 ****
--- 53,65 ----
public class AuthList {
private final LinkedList<AuthTimeWithHash> entries;
private final int lifespan;
+ // entries.getLast().ctime, updated after each cleanup.
+ private volatile int oldestTime = Integer.MIN_VALUE;
+
/**
* Constructs a AuthList.
*/
public AuthList(int lifespan) {
this.lifespan = lifespan;
*** 70,79 ****
--- 73,84 ----
public void put(AuthTimeWithHash t, KerberosTime currentTime)
throws KrbApErrException {
if (entries.isEmpty()) {
entries.addFirst(t);
+ oldestTime = t.ctime;
+ return;
} else {
AuthTimeWithHash temp = entries.getFirst();
int cmp = temp.compareTo(t);
if (cmp < 0) {
// This is the most common case, newly received authenticator
*** 104,131 ****
}
}
// let us cleanup while we are here
long timeLimit = currentTime.getSeconds() - lifespan;
ListIterator<AuthTimeWithHash> it = entries.listIterator(0);
! AuthTimeWithHash temp = null;
! int index = -1;
while (it.hasNext()) {
// search expired timestamps.
temp = it.next();
if (temp.ctime < timeLimit) {
! index = entries.indexOf(temp);
break;
}
}
! // It would be nice if LinkedList has a method called truncate(index).
! if (index > -1) {
! do {
! // remove expired timestamps from the list.
! entries.removeLast();
! } while(entries.size() > index);
}
}
public boolean isEmpty() {
return entries.isEmpty();
}
--- 109,146 ----
}
}
// let us cleanup while we are here
long timeLimit = currentTime.getSeconds() - lifespan;
+ long veryOld = timeLimit - (lifespan > 60 ? 60 : lifespan);
+
+ // Only trigger a cleanup when very old entries exist
+ // (lifespan + 1 min ago). This ensures a cleanup is done
+ // at most every minute.
+ if (oldestTime > veryOld) {
+ return;
+ }
+
+ // and we remove the *enough* old ones (1 lifetime ago)
ListIterator<AuthTimeWithHash> it = entries.listIterator(0);
! AuthTimeWithHash temp;
while (it.hasNext()) {
// search expired timestamps.
temp = it.next();
if (temp.ctime < timeLimit) {
! // It would be nice if ListIterator has a method called stripHere()
! while (!entries.isEmpty()) {
! if (entries.removeLast() == temp) {
break;
}
}
! break;
! }
}
+
+ AuthTimeWithHash last = entries.peekLast();
+ oldestTime = last == null ? Integer.MIN_VALUE : last.ctime;
}
public boolean isEmpty() {
return entries.isEmpty();
}
< prev index next >