1'\" '\" The contents of this file are subject to the AOLserver Public License '\" Version 1.1 (the "License"); you may not use this file except in '\" compliance with the License. You may obtain a copy of the License at '\" http://aolserver.com/. '\" '\" Software distributed under the License is distributed on an "AS IS" '\" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See '\" the License for the specific language governing rights and limitations '\" under the License. '\" '\" The Original Code is AOLserver Code and related documentation '\" distributed by AOL. '\" '\" The Initial Developer of the Original Code is America Online, '\" Inc. Portions created by AOL are Copyright (C) 1999 America Online, '\" Inc. All Rights Reserved. '\" '\" Alternatively, the contents of this file may be used under the terms '\" of the GNU General Public License (the "GPL"), in which case the '\" provisions of GPL are applicable instead of those above. If you wish '\" to allow use of your version of this file only under the terms of the '\" GPL and not to allow others to use your version of this file under the '\" License, indicate your decision by deleting the provisions above and '\" replace them with the notice and other provisions required by the GPL. '\" If you do not delete the provisions above, a recipient may use your '\" version of this file under either the License or the GPL. '\" '\" '\" $Header: /cvsroot/aolserver/aolserver/doc/ns_cache.n,v 1.6 2009/01/31 21:35:08 gneumann Exp $ '\" '\" '\" transliterated from index.html by davis@xarg.net 2002-11-10 '\" but without the useful diagrams from the html. '\" '\" The definitions below are for supplemental macros used in Tcl/Tk '\" manual entries. '\" '\" .AP type name in/out ?indent? '\" Start paragraph describing an argument to a library procedure. '\" type is type of argument (int, etc.), in/out is either "in", "out", '\" or "in/out" to describe whether procedure reads or modifies arg, '\" and indent is equivalent to second arg of .IP (shouldn't ever be '\" needed; use .AS below instead) '\" '\" .AS ?type? ?name? '\" Give maximum sizes of arguments for setting tab stops. Type and '\" name are examples of largest possible arguments that will be passed '\" to .AP later. If args are omitted, default tab stops are used. '\" '\" .BS '\" Start box enclosure. From here until next .BE, everything will be '\" enclosed in one large box. '\" '\" .BE '\" End of box enclosure. '\" '\" .CS '\" Begin code excerpt. '\" '\" .CE '\" End code excerpt. '\" '\" .VS ?version? ?br? '\" Begin vertical sidebar, for use in marking newly-changed parts '\" of man pages. The first argument is ignored and used for recording '\" the version when the .VS was added, so that the sidebars can be '\" found and removed when they reach a certain age. If another argument '\" is present, then a line break is forced before starting the sidebar. '\" '\" .VE '\" End of vertical sidebar. '\" '\" .DS '\" Begin an indented unfilled display. '\" '\" .DE '\" End of indented unfilled display. '\" '\" .SO '\" Start of list of standard options for a Tk widget. The '\" options follow on successive lines, in four columns separated '\" by tabs. '\" '\" .SE '\" End of list of standard options for a Tk widget. '\" '\" .OP cmdName dbName dbClass '\" Start of description of a specific option. cmdName gives the '\" option's name as specified in the class command, dbName gives '\" the option's name in the option database, and dbClass gives '\" the option's class in the option database. '\" '\" .UL arg1 arg2 '\" Print arg1 underlined, then print arg2 normally. '\" '\" RCS: @(#) $Id: man.macros,v 1.1 2006/06/26 00:29:11 jgdavidson Exp $ '\" '\" # Set up traps and other miscellaneous stuff for Tcl/Tk man pages. .if t .wh -1.3i ^B .nr ^l \n(.l .ad b '\" # Start an argument description .de AP .ie !"\\$4"" .TP \\$4 .el \{\ . ie !"\\$2"" .TP \\n()Cu . el .TP 15 .\} .ta \\n()Au \\n()Bu .ie !"\\$3"" \{\ \&\\$1 \\fI\\$2\\fP (\\$3) .\".b .\} .el \{\ .br .ie !"\\$2"" \{\ \&\\$1 \\fI\\$2\\fP .\} .el \{\ \&\\fI\\$1\\fP .\} .\} .. '\" # define tabbing values for .AP .de AS .nr )A 10n .if !"\\$1"" .nr )A \\w'\\$1'u+3n .nr )B \\n()Au+15n .\" .if !"\\$2"" .nr )B \\w'\\$2'u+\\n()Au+3n .nr )C \\n()Bu+\\w'(in/out)'u+2n .. .AS Tcl_Interp Tcl_CreateInterp in/out '\" # BS - start boxed text '\" # ^y = starting y location '\" # ^b = 1 .de BS .br .mk ^y .nr ^b 1u .if n .nf .if n .ti 0 .if n \l'\\n(.lu\(ul' .if n .fi .. '\" # BE - end boxed text (draw box now) .de BE .nf .ti 0 .mk ^t .ie n \l'\\n(^lu\(ul' .el \{\ .\" Draw four-sided box normally, but don't draw top of .\" box if the box started on an earlier page. .ie !\\n(^b-1 \{\ \h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul' .\} .el \}\ \h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul' .\} .\} .fi .br .nr ^b 0 .. '\" # VS - start vertical sidebar '\" # ^Y = starting y location '\" # ^v = 1 (for troff; for nroff this doesn't matter) .de VS .if !"\\$2"" .br .mk ^Y .ie n 'mc \s12\(br\s0 .el .nr ^v 1u .. '\" # VE - end of vertical sidebar .de VE .ie n 'mc .el \{\ .ev 2 .nf .ti 0 .mk ^t \h'|\\n(^lu+3n'\L'|\\n(^Yu-1v\(bv'\v'\\n(^tu+1v-\\n(^Yu'\h'-|\\n(^lu+3n' .sp -1 .fi .ev .\} .nr ^v 0 .. '\" # Special macro to handle page bottom: finish off current '\" # box/sidebar if in box/sidebar mode, then invoked standard '\" # page bottom macro. .de ^B .ev 2 'ti 0 'nf .mk ^t .if \\n(^b \{\ .\" Draw three-sided box if this is the box's first page, .\" draw two sides but no top otherwise. .ie !\\n(^b-1 \h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c .el \h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c .\} .if \\n(^v \{\ .nr ^x \\n(^tu+1v-\\n(^Yu \kx\h'-\\nxu'\h'|\\n(^lu+3n'\ky\L'-\\n(^xu'\v'\\n(^xu'\h'|0u'\c .\} .bp 'fi .ev .if \\n(^b \{\ .mk ^y .nr ^b 2 .\} .if \\n(^v \{\ .mk ^Y .\} .. '\" # DS - begin display .de DS .RS .nf .sp .. '\" # DE - end display .de DE .fi .RE .sp .. '\" # SO - start of list of standard options .de SO .SH "STANDARD OPTIONS" .LP .nf .ta 5.5c 11c .ft B .. '\" # SE - end of list of standard options .de SE .fi .ft R .LP See the \\fBoptions\\fR manual entry for details on the standard options. .. '\" # OP - start of full description for a single option .de OP .LP .nf .ta 4c Command-Line Name: \\fB\\$1\\fR Database Name: \\fB\\$2\\fR Database Class: \\fB\\$3\\fR .fi .IP .. '\" # CS - begin code excerpt .de CS .RS .nf .ta .25i .5i .75i 1i .. '\" # CE - end code excerpt .de CE .fi .RE .. .de UL \\$1\l'|0\(ul'\\$2 .. .TH ns_cache 3aolserver 4.0 AOLserver "AOLserver Built-In Commands" .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME ns_cache \- Cache arbitrary data .SH SYNOPSIS .nf \fBns_cache append \fIcachename key string ?string ...?\fR \fBns_cache create \fIcachename\fR ?\fB-size\fI maxsize\fR?\fR ?\fB-timeout\fI timeout\fR? ?\fB-thread\fI thread\fR? \fBns_cache eval \fIcachename key script\fR \fBns_cache flush \fIcachename key\fR \fBns_cache get \fIcachename key \fR?\fIvarname\fR? \fBns_cache incr \fIcachename key ?value?\fR \fBns_cache lappend \fIcachename key string ?string ...?\fR \fBns_cache names \fIcachename ?pattern?\fR \fBns_cache set \fIcachename key string\fR .fi .BE .SH DESCRIPTION .PP AOLserver implements a C API for caching arbitrary data. This module provides a Tcl API on top of the C API. A cache, in this context, is simply a dictionary that maps keys to values. Keys are always stored as NUL-terminated strings. How values are stored depends on the type of cache. .TP \fBns_cache create \fIcachename\fR ?\fB-size\fI maxsize\fR?\fR ?\fB-timeout\fI timeout\fR? ?\fB-thread\fI thread\fR? This command creates a new cache named \fIcachename\fR. If -thread is given and is true, then it is a thread-private cache. Otherwise it is a global cache. If \fImaxsize\fR is given, then it is a sized-based cache. If \fItimeout\fR is given, then it is a timeout-based cache. Otherwise, it is a timeout-based cache with an infinite timeout, meaning it will never be flushed. This command returns nothing if it is successful. .TP \fBns_cache eval \fIcachename key script\fR This command atomically sets and gets a cache value. First, it looks up key in the cache named cachename. If it finds an entry, it returns the value of that entry. Otherwise, it executes script, stores the return value in the cache, and also returns that value. Script may optionally use the return command to return its value. For example, this will store the value "2" in mycache, if mykey is not already present: ns_cache eval mycache mykey { expr {1+1} } This will also store the value "2" in mycache: ns_cache eval mycache mykey { return [expr {1+1}] } If \fIscript\fR raises an error, or exits with break or continue, then ns_cache eval simply returns the same condition without modifying the cache. .TP \fBns_cache flush \fIcachename key\fR This command removes the entry for \fIkey\fR from the cache named \fIcachename\fR. If the cache has no entry for \fIkey\fR, then nothing happens. For global caches, \fBns_cache flush\fR interacts with \fBns_cache eval\fR. Suppose thread 1 has called get_thing A and is executing the long operation to compute the value for A. Thread 2 calls \fBget_thing A\fR and starts waiting for thread 1 to finish. Thread 3 calls \fBns_cache flush thing_cache A\fR. Thread 1 will continue executing the long operation, but thread 2 will also start the long operation. When thread 1 completes the long operation, \fBns_cache eval\fR returns the (now stale) value it computed, but it does \fInot\fR store the value in the cache. When thread 2 completes the long operation, \fBns_cache eval\fR stores the (fresh) value it computed in the cache and returns the fresh value. .TP \fBns_cache get \fIcachename key \fR?\fIvarname\fR? This command looks up \fIkey\fR in the specified cache. It operates differently depending on whether \fIvarname\fR was given. If \fIvarname\fR absent and the key exists the value is returned and if the key is missing an error is raised. If \fIvarname\fR is provided and the key exists the command sets \fIvarname\fR to the value and returns 1, otherwise it returns 0. .TP \fBns_cache names \fIcachename ?pattern?\fR This command returns a list of all keys currently in the specified cache. If \fIpattern\fR is specified, only matching entries are returned (match pattern syntax like in \fBstring match\fR). If the cache is thread-private, then the list only includes keys that are in the thread's private cache. .TP \fBns_cache set \fIcachename key value\fR This command stores value for key in the specified cache. .SH CACHE TYPES .PP ns_cache supports three types of caches: .B Global Size-Limited Cache ns_cache create cachename -size maxsize .PP Entries in a cache of this type are accessible to all threads. Each cache has its own mutex that protects access to its entries. .PP Cache values are stored as counted strings, so arbitrary binary data can be cached. A global cache stores strings instead of Tcl objects to prevent race conditions that could lead to heap corruption. .PP The cache has a maximum size specified when the cache is created. The size of the cache is the sum of the sizes of all the values in the cache; keys do not count toward a cache's size. If inserting a value into the cache makes the cache's size exceed its maximum, then cache entries are evicted starting with the least-recently used entry until the size is below the maximum size (or until only the new value remains in the cache). .B Global Time-Limited Cache ns_cache create cachename -timeout timeout .PP Entries in a cache of this type are accessible to all threads. Each cache has its own mutex that protects access to its entries. .PP Cache values are stored as counted strings, as in a global size-limited cache. .PP The cache has a maximum entry lifetime, called its \fItimeout\fR, specified (in seconds) when the cache is created. Every \fItimeout\fR seconds, AOLserver flushes all cache entries that have not were not created or accessed in the last \fItimeout\fR seconds. .B Thread-Private Size-Limited Cache ns_cache create cachename -size maxsize -thread 1 .PP Each thread in AOLserver automatically gets its own private cache named \fIcachename\fR. Since a thread-private cache is only accessed by one thread, access to it does not require a mutex. Entries in one thread's cache are not visible to any other thread. .PP Cache values are stored as Tcl objects. When a value is stored in the cache, nscache computes its string form and uses the length of the string as the size of the value. .PP The cache has a maximum size, like a global size-limited cache. However, because of the way the cache value sizes are computed, the actual memory usage of the cache values may be several times larger than \fImaxsize\fR. .PP Thread-private caches may offer higher performance if the cached values are complex objects such as lists or scripts, but require more storage than global caches. .SH "SEE ALSO" Ns_Cache(3), nsv(n)