File: weakptr.xml

package info (click to toggle)
gap 4.15.1-1
  • links: PTS
  • area: main
  • in suites: forky, sid
  • size: 110,212 kB
  • sloc: ansic: 97,261; xml: 48,343; cpp: 13,946; sh: 4,900; perl: 1,650; javascript: 255; makefile: 252; ruby: 9
file content (235 lines) | stat: -rw-r--r-- 8,223 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->
<!-- %% -->
<!-- %W  weakptr.tex              GAP documentation               Steve Linton -->
<!-- %% -->
<!-- %% -->
<!-- %Y  Copyright 1997,  The GAP Project -->
<!-- %% -->
<!-- %%  This file describes the use of weak pointers -->
<!-- %% -->

<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->
<Chapter Label="Weak Pointers">
<Heading>Weak Pointers</Heading>

This chapter describes the use of the kernel feature of <E>weak pointers</E>.
This feature is primarily intended for use only in &GAP; internals, and
should be used extremely carefully otherwise.
<P/>
The garbage collector (see Section <Ref Subsect="Garbage Collection"/>)
is the part of the kernel that manages memory in the user's workspace.
It will  normally only reclaim  the storage used by  an
object when the object cannot be reached as a subobject of any &GAP; variable,
or from any reference in the kernel.
We say that any link to object <M>a</M> from object <M>b</M>
<Q>keeps object <M>a</M> alive</Q>, as long as <M>b</M> is alive.
It is occasionally convenient, however, to have a link to an object
which <E>does not keep it alive</E>, and this is a weak pointer.
The most common use is in caches, and similar structures,
where it is only necessary to remember how to solve problem <M>x</M>
as long as some other link to <M>x</M> exists.
<P/>
The  following section <Ref Sect="Weak Pointer Objects"/> describes
the semantics of the objects that contain weak pointers.
Following sections describe the functions available to manipulate them.


<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->
<Section Label="Weak Pointer Objects">
<Heading>Weak Pointer Objects</Heading>

A <E>weak pointer object</E> is similar to a mutable plain list,
except that it does not keep its subobjects alive during a garbage collection.
From the &GAP; viewpoint this means that its entries may become unbound,
apparently spontaneously, at any time.
Considerable care is therefore needed in programming with such an object.


<ManSection>
<Func Name="WeakPointerObj" Arg="list"/>

<Description>
<Ref Func="WeakPointerObj"/> returns a weak pointer object which contains
the same subobjects as the list <A>list</A>,
that is it returns a <E>shallow</E> weak copy of <A>list</A>.
<P/>
<Example><![CDATA[
gap> w := WeakPointerObj( [ 1, , [2,3], fail, rec( a := 1) ] );
WeakPointerObj( [ 1, , [ 2, 3 ], fail, rec( a := 1 ) ] )
]]></Example>
<P/>
After some computations involving garbage collections
(but not necessarily in the <E>first</E> garbage collection after
the above assignment),
&GAP; will notice that the list and the record stored in <C>w</C>
are not referenced by other objects than <C>w</C>,
and that therefore these entries may disappear.
<P/>
<Log><![CDATA[
gap> CollectGarbage( true );

... (perhaps more computations and garbage collections) ...

gap> CollectGarbage( true );
gap> w;
WeakPointerObj( [ 1, , , fail ] )
]]></Log>
<P/>
Note that <C>w</C> has failed to keep its list and record subobjects alive
during the garbage collections.
Certain subobjects, such as small integers and elements of small finite
fields, are not stored in the workspace,
and so are not subject to garbage collection, while certain other objects,
such as the boolean values, are always reachable from global variables
or the kernel and so are never garbage collected.
<P/>
Subobjects reachable without going through a weak pointer object do not
evaporate, as in:
<P/>
<Example><![CDATA[
gap> w := WeakPointerObj( [ 1, , , fail ] );
WeakPointerObj( [ 1, , , fail ] )
gap> l := [1,2,3];;
gap> w[1] := l;;
gap> w;
WeakPointerObj( [ [ 1, 2, 3 ], , , fail ] )
gap> CollectGarbage( true );
gap> w;
WeakPointerObj( [ [ 1, 2, 3 ], , , fail ] )
]]></Example>
<P/>
Note also that the global variables <C>last</C>, <C>last2</C> and <C>last3</C>
will keep things alive &ndash;this can be confusing when debugging.
</Description>
</ManSection>

</Section>


<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->
<Section Label="Low Level Access Functions for Weak Pointer Objects">
<Heading>Low Level Access Functions for Weak Pointer Objects</Heading>

<Index>ElmWPObj</Index>
<ManSection>
<Func Name="SetElmWPObj" Arg="wp, pos, val"/>
<Func Name="UnbindElmWPObj" Arg="wp, pos"/>
<Func Name="ElmWPObj" Arg="wp, pos"/>
<Func Name="IsBoundElmWPObj" Arg="wp, pos"/>
<Func Name="LengthWPObj" Arg="wp"/>

<Description>
The functions <Ref Func="SetElmWPObj"/> and
<Ref Func="UnbindElmWPObj"/> set and unbind entries in a weak pointer object.
<P/>
The function <Ref Func="ElmWPObj"/> returns the element at position
<A>pos</A> of the weak pointer object <A>wp</A>, if there is one,
and <K>fail</K> otherwise.
A return value of <K>fail</K> can thus arise either because
(a) the value <K>fail</K> is stored at position <A>pos</A>, or
(b) no value is stored at position <A>pos</A>.
Since <K>fail</K> cannot vanish in a garbage collection, these two cases can
safely be distinguished by a <E>subsequent</E> call to
<Ref Func="IsBoundElmWPObj"/>,
which returns <K>true</K> if there is currently a value bound at position
<A>pos</A> of <A>wp</A> and <K>false</K> otherwise.
<P/>
Note that it is <E>not</E> safe to write:
<P/>
<C>if IsBoundElmWPObj(w,i) then x:= ElmWPObj(w,i); fi;</C>
<P/>
and treat <C>x</C> as reliably containing a value taken from <C>w</C>,
as a badly timed garbage collection could leave <C>x</C> containing
<K>fail</K>.
Instead use
<P/>
<C>x := ElmWPObj(w,i); if x &lt;> fail or IsBoundElmWPObj(w,i) then . . .</C>.
<P/>
Here is an example.
<P/>
<Example><![CDATA[
gap> w := WeakPointerObj( [ 1, , [2,3], fail, rec() ] );
WeakPointerObj( [ 1, , [ 2, 3 ], fail, rec(  ) ] )
gap> SetElmWPObj(w,5,[]);
gap> w;
WeakPointerObj( [ 1, , [ 2, 3 ], fail, [  ] ] )
gap> UnbindElmWPObj(w,1);
gap> w;
WeakPointerObj( [ , , [ 2, 3 ], fail, [  ] ] )
gap> ElmWPObj(w,3);
[ 2, 3 ]
gap> ElmWPObj(w,1);
fail
]]></Example>
<P/>
Now after some computations and garbage collections <M>\ldots</M>
<P/>
<Example><![CDATA[
gap> 2;; 3;; 4;; CollectGarbage( true );  # clear last, last2, last3
]]></Example>
<P/>
<M>\ldots</M> we get the following.
<P/>
<Log><![CDATA[
gap> ElmWPObj(w,3);
fail
gap> w;
WeakPointerObj( [ , , , fail ] )
gap> ElmWPObj(w,4);
fail
gap> IsBoundElmWPObj(w,3);
false
gap> IsBoundElmWPObj(w,4);
true
]]></Log>
</Description>
</ManSection>

</Section>


<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->
<Section Label="Accessing Weak Pointer Objects as Lists">
<Heading>Accessing Weak Pointer Objects as Lists</Heading>

Weak pointer objects are members of <C>ListsFamily</C>
and the categories <Ref Filt="IsList"/>
and <Ref Filt="IsMutable"/>.
Methods based  on  the low-level functions in  the previous
section, are  installed for the list  access operations,  enabling them to be
used as lists.    However, it is  <E>not recommended</E>  that  these be used   in
programming. They   are  supplied mainly as   a convenience  for  interactive
working, and   may not be   safe, since functions  and methods  for lists may
assume that after <C>IsBound(w[i])</C> returns <K>true</K>,
access to <C>w[i]</C> is safe.

</Section>


<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->
<Section Label="Copying Weak Pointer Objects">
<Heading>Copying Weak Pointer Objects</Heading>

A <Ref Oper="ShallowCopy"/> method is installed,
which makes a new weak pointer object
containing the same objects as the original.
<P/>
It is possible to apply <Ref Func="StructuralCopy"/>
to a weak pointer object, obtaining
a new weak  pointer object containing copies of  the objects in the original.
This <E>may not be safe</E> if a badly timed garbage collection occurs during
copying.
<P/>
Applying <Ref Func="Immutable"/> to a weak pointer object
produces an immutable plain
list containing immutable copies of the objects contained in the weak pointer
object. An immutable weak pointer object is a contradiction in terms.

</Section>
</Chapter>


<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->
<!-- %% -->
<!-- %E -->